manually merged
This commit is contained in:
commit
a04fc26c54
@ -1,5 +1,16 @@
|
|||||||
#!/bin/sh
|
#!/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` ]
|
if [ `tail -c1 $BK_FILE` ]
|
||||||
then
|
then
|
||||||
echo "File $BK_FILE does not end with a new-line character!"
|
echo "File $BK_FILE does not end with a new-line character!"
|
||||||
|
@ -49,4 +49,5 @@ enum options_client
|
|||||||
#ifdef HAVE_NDBCLUSTER_DB
|
#ifdef HAVE_NDBCLUSTER_DB
|
||||||
,OPT_NDBCLUSTER,OPT_NDB_CONNECTSTRING
|
,OPT_NDBCLUSTER,OPT_NDB_CONNECTSTRING
|
||||||
#endif
|
#endif
|
||||||
|
,OPT_IGNORE_TABLE
|
||||||
};
|
};
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
#include <m_string.h>
|
#include <m_string.h>
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
#include <hash.h>
|
||||||
|
|
||||||
#include "client_priv.h"
|
#include "client_priv.h"
|
||||||
#include "mysql.h"
|
#include "mysql.h"
|
||||||
@ -130,6 +131,15 @@ const char *compatible_mode_names[]=
|
|||||||
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
|
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
|
||||||
"", compatible_mode_names, NULL};
|
"", 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[] =
|
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},
|
(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,
|
{"host", 'h', "Connect to host.", (gptr*) ¤t_host,
|
||||||
(gptr*) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
(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 ...",
|
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
|
||||||
(gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR,
|
(gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR,
|
||||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
@ -506,6 +521,28 @@ static void write_footer(FILE *sql_file)
|
|||||||
} /* write_footer */
|
} /* 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
|
static my_bool
|
||||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
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:
|
case (int) OPT_TABLES:
|
||||||
opt_databases=0;
|
opt_databases=0;
|
||||||
break;
|
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:
|
case (int) OPT_COMPATIBLE:
|
||||||
{
|
{
|
||||||
char buff[255];
|
char buff[255];
|
||||||
char *end= compatible_mode_normal_str;
|
char *end= compatible_mode_normal_str;
|
||||||
int i;
|
int i;
|
||||||
@ -617,6 +678,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
}
|
}
|
||||||
if (end!=compatible_mode_normal_str)
|
if (end!=compatible_mode_normal_str)
|
||||||
end[-1]= 0;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case (int) OPT_MYSQL_PROTOCOL:
|
case (int) OPT_MYSQL_PROTOCOL:
|
||||||
@ -1991,6 +2058,14 @@ static int init_dumping(char *database)
|
|||||||
} /* init_dumping */
|
} /* 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)
|
static int dump_all_tables_in_db(char *database)
|
||||||
{
|
{
|
||||||
@ -1998,6 +2073,12 @@ static int dump_all_tables_in_db(char *database)
|
|||||||
uint numrows;
|
uint numrows;
|
||||||
char table_buff[NAME_LEN*2+3];
|
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))
|
if (init_dumping(database))
|
||||||
return 1;
|
return 1;
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
@ -2006,7 +2087,7 @@ static int dump_all_tables_in_db(char *database)
|
|||||||
{
|
{
|
||||||
DYNAMIC_STRING query;
|
DYNAMIC_STRING query;
|
||||||
init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
|
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, quote_name(table, table_buff, 1));
|
||||||
dynstr_append(&query, " READ /*!32311 LOCAL */,");
|
dynstr_append(&query, " READ /*!32311 LOCAL */,");
|
||||||
@ -2022,13 +2103,17 @@ static int dump_all_tables_in_db(char *database)
|
|||||||
DBerror(sock, "when doing refresh");
|
DBerror(sock, "when doing refresh");
|
||||||
/* We shall continue here, if --force was given */
|
/* We shall continue here, if --force was given */
|
||||||
}
|
}
|
||||||
while ((table = getTableName(0)))
|
while ((table= getTableName(0)))
|
||||||
{
|
{
|
||||||
numrows = getTableStructure(table, database);
|
char *end= strmov(afterdot, table);
|
||||||
if (!dFlag && numrows > 0)
|
if (include_table(hash_key, end - hash_key))
|
||||||
dumpTable(numrows,table);
|
{
|
||||||
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
|
numrows = getTableStructure(table, database);
|
||||||
order_by= 0;
|
if (!dFlag && numrows > 0)
|
||||||
|
dumpTable(numrows,table);
|
||||||
|
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
order_by= 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,7 @@ NDB_VERSION_STATUS="alpha"
|
|||||||
# Remember that regexps needs to quote [ and ] since this is run through m4
|
# 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_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"`
|
||||||
MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"`
|
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
|
# The port should be constant for a LONG time
|
||||||
MYSQL_TCP_PORT_DEFAULT=3306
|
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);
|
Vio* vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost);
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
Vio* vio_new_win32pipe(HANDLE hPipe);
|
Vio* vio_new_win32pipe(HANDLE hPipe);
|
||||||
Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map,
|
Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map,
|
||||||
HANDLE handle_map,
|
HANDLE handle_map,
|
||||||
HANDLE event_server_wrote,
|
HANDLE event_server_wrote,
|
||||||
HANDLE event_server_read,
|
HANDLE event_server_read,
|
||||||
HANDLE event_client_wrote,
|
HANDLE event_client_wrote,
|
||||||
HANDLE event_client_read);
|
HANDLE event_client_read,
|
||||||
int vio_read_pipe(Vio *vio, gptr buf, int size);
|
HANDLE event_conn_closed);
|
||||||
int vio_write_pipe(Vio *vio, const gptr buf, int size);
|
int vio_read_pipe(Vio *vio, gptr buf, int size);
|
||||||
int vio_close_pipe(Vio * vio);
|
int vio_write_pipe(Vio *vio, const gptr buf, int size);
|
||||||
|
int vio_close_pipe(Vio * vio);
|
||||||
#else
|
#else
|
||||||
#define HANDLE void *
|
#define HANDLE void *
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
@ -197,6 +198,7 @@ struct st_vio
|
|||||||
HANDLE event_server_read;
|
HANDLE event_server_read;
|
||||||
HANDLE event_client_wrote;
|
HANDLE event_client_wrote;
|
||||||
HANDLE event_client_read;
|
HANDLE event_client_read;
|
||||||
|
HANDLE event_conn_closed;
|
||||||
long shared_memory_remain;
|
long shared_memory_remain;
|
||||||
char *shared_memory_pos;
|
char *shared_memory_pos;
|
||||||
NET *net;
|
NET *net;
|
||||||
|
@ -332,7 +332,7 @@ buf_read_page(
|
|||||||
if (err == DB_TABLESPACE_DELETED) {
|
if (err == DB_TABLESPACE_DELETED) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(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",
|
"InnoDB: but the tablespace does not exist or is just being dropped.\n",
|
||||||
(ulong) space, (ulong) offset);
|
(ulong) space, (ulong) offset);
|
||||||
}
|
}
|
||||||
|
@ -207,12 +207,14 @@ loop:
|
|||||||
In a crash recovery we already have all the tablespace objects created.
|
In a crash recovery we already have all the tablespace objects created.
|
||||||
This function compares the space id information in the InnoDB data dictionary
|
This function compares the space id information in the InnoDB data dictionary
|
||||||
to what we already read with fil_load_single_table_tablespaces().
|
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
|
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 */
|
ibool in_crash_recovery) /* in: are we doing a crash recovery */
|
||||||
{
|
{
|
||||||
dict_table_t* sys_tables;
|
dict_table_t* sys_tables;
|
||||||
@ -283,6 +285,14 @@ loop:
|
|||||||
FALSE, TRUE, TRUE);
|
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);
|
mem_free(name);
|
||||||
|
|
||||||
if (space_id > max_space_id) {
|
if (space_id > max_space_id) {
|
||||||
@ -797,8 +807,18 @@ dict_load_table(
|
|||||||
/* Ok; (if we did a crash recovery then the tablespace
|
/* Ok; (if we did a crash recovery then the tablespace
|
||||||
can already be in the memory cache) */
|
can already be in the memory cache) */
|
||||||
} else {
|
} 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 */
|
/* 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
|
/* We failed to find a sensible tablespace
|
||||||
file */
|
file */
|
||||||
|
|
||||||
|
@ -469,6 +469,10 @@ fil_node_open_file(
|
|||||||
ulint size_low;
|
ulint size_low;
|
||||||
ulint size_high;
|
ulint size_high;
|
||||||
ibool ret;
|
ibool ret;
|
||||||
|
byte* buf2;
|
||||||
|
byte* page;
|
||||||
|
ibool success;
|
||||||
|
ulint space_id;
|
||||||
|
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
ut_ad(mutex_own(&(system->mutex)));
|
ut_ad(mutex_own(&(system->mutex)));
|
||||||
@ -497,6 +501,8 @@ fil_node_open_file(
|
|||||||
system->n_open++;
|
system->n_open++;
|
||||||
|
|
||||||
if (node->size == 0) {
|
if (node->size == 0) {
|
||||||
|
ut_a(space->purpose != FIL_LOG);
|
||||||
|
|
||||||
os_file_get_size(node->handle, &size_low, &size_high);
|
os_file_get_size(node->handle, &size_low, &size_high);
|
||||||
|
|
||||||
size_bytes = (((ib_longlong)size_high) << 32)
|
size_bytes = (((ib_longlong)size_high) << 32)
|
||||||
@ -510,6 +516,46 @@ fil_node_open_file(
|
|||||||
|
|
||||||
ut_a(space->id != 0);
|
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) {
|
if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
|
||||||
node->size = (ulint) ((size_bytes / (1024 * 1024))
|
node->size = (ulint) ((size_bytes / (1024 * 1024))
|
||||||
* ((1024 * 1024) / UNIV_PAGE_SIZE));
|
* ((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
|
Tries to open a single-table tablespace and optionally checks the space id is
|
||||||
it. If does not succeed, prints an error message to the .err log. This
|
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
|
function is used to open a tablespace when we start up mysqld, and also in
|
||||||
to the dictionary cache. NOTE that we assume this operation is used under the
|
IMPORT TABLESPACE.
|
||||||
protection of the dictionary mutex, so that two users cannot race here. This
|
NOTE that we assume this operation is used either at the database startup
|
||||||
operation does not leave the file associated with the tablespace open, but
|
or under the protection of the dictionary mutex, so that two users cannot
|
||||||
closes it after we have looked at the space id in it. */
|
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
|
ibool
|
||||||
fil_open_single_table_tablespace(
|
fil_open_single_table_tablespace(
|
||||||
/*=============================*/
|
/*=============================*/
|
||||||
/* out: TRUE if success */
|
/* out: TRUE if success */
|
||||||
ulint id, /* in: space id */
|
ibool check_space_id, /* in: should we check that the space
|
||||||
const char* name) /* in: table name in the
|
id in the file is right; we assume
|
||||||
databasename/tablename format */
|
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;
|
os_file_t file;
|
||||||
char* filepath;
|
char* filepath;
|
||||||
@ -2551,6 +2605,12 @@ fil_open_single_table_tablespace(
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!check_space_id) {
|
||||||
|
space_id = id;
|
||||||
|
|
||||||
|
goto skip_check;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the first page of the tablespace */
|
/* Read the first page of the tablespace */
|
||||||
|
|
||||||
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
|
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
|
||||||
@ -2563,6 +2623,8 @@ fil_open_single_table_tablespace(
|
|||||||
|
|
||||||
space_id = fsp_header_get_space_id(page);
|
space_id = fsp_header_get_space_id(page);
|
||||||
|
|
||||||
|
ut_free(buf2);
|
||||||
|
|
||||||
if (space_id != id) {
|
if (space_id != id) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
@ -2583,6 +2645,7 @@ fil_open_single_table_tablespace(
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_check:
|
||||||
success = fil_space_create(filepath, space_id, FIL_TABLESPACE);
|
success = fil_space_create(filepath, space_id, FIL_TABLESPACE);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
@ -2595,7 +2658,6 @@ fil_open_single_table_tablespace(
|
|||||||
fil_node_create(filepath, 0, space_id, FALSE);
|
fil_node_create(filepath, 0, space_id, FALSE);
|
||||||
func_exit:
|
func_exit:
|
||||||
os_file_close(file);
|
os_file_close(file);
|
||||||
ut_free(buf2);
|
|
||||||
mem_free(filepath);
|
mem_free(filepath);
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
@ -2662,7 +2724,7 @@ fil_load_single_table_tablespace(
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Error: could not open single-table tablespace file\n"
|
"InnoDB: Error: could not open single-table tablespace file\n"
|
||||||
"InnoDB: %s!\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: 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: To fix the problem and start mysqld:\n"
|
||||||
"InnoDB: 1) If there is a permission problem in the file and mysqld cannot\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;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We do not measure the size of the file, that is why we pass the 0
|
/* We do not use the size information we have about the file, because
|
||||||
below */
|
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);
|
fil_node_create(filepath, 0, space_id, FALSE);
|
||||||
func_exit:
|
func_exit:
|
||||||
|
@ -18,12 +18,14 @@ Created 4/24/1996 Heikki Tuuri
|
|||||||
In a crash recovery we already have all the tablespace objects created.
|
In a crash recovery we already have all the tablespace objects created.
|
||||||
This function compares the space id information in the InnoDB data dictionary
|
This function compares the space id information in the InnoDB data dictionary
|
||||||
to what we already read with fil_load_single_table_tablespaces().
|
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
|
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 */
|
ibool in_crash_recovery); /* in: are we doing a crash recovery */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Finds the first table name in the given database. */
|
Finds the first table name in the given database. */
|
||||||
|
@ -366,19 +366,29 @@ fil_create_new_single_table_tablespace(
|
|||||||
tablespace file in pages,
|
tablespace file in pages,
|
||||||
must be >= FIL_IBD_FILE_INITIAL_SIZE */
|
must be >= FIL_IBD_FILE_INITIAL_SIZE */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Tries to open a single-table tablespace and checks the space id is right in
|
Tries to open a single-table tablespace and optionally checks the space id is
|
||||||
it. If does not succeed, prints an error message to the .err log. This
|
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
|
function is used to open a tablespace when we start up mysqld, and also in
|
||||||
to the dictionary cache. NOTE that we assume this operation is used under the
|
IMPORT TABLESPACE.
|
||||||
protection of the dictionary mutex, so that two users cannot race here. */
|
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
|
ibool
|
||||||
fil_open_single_table_tablespace(
|
fil_open_single_table_tablespace(
|
||||||
/*=============================*/
|
/*=============================*/
|
||||||
/* out: TRUE if success */
|
/* out: TRUE if success */
|
||||||
ulint id, /* in: space id */
|
ibool check_space_id, /* in: should we check that the space
|
||||||
const char* name); /* in: table name in the
|
id in the file is right; we assume
|
||||||
databasename/tablename format */
|
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
|
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
|
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
|
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
|
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
|
|
||||||
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. */
|
|
||||||
|
|
||||||
int
|
int
|
||||||
row_discard_tablespace_for_mysql(
|
row_discard_tablespace_for_mysql(
|
||||||
|
@ -414,6 +414,19 @@ struct trx_struct{
|
|||||||
replication slave, this is the
|
replication slave, this is the
|
||||||
position in the log file up to which
|
position in the log file up to which
|
||||||
replication has processed */
|
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
|
os_thread_id_t mysql_thread_id;/* id of the MySQL thread associated
|
||||||
with this transaction object */
|
with this transaction object */
|
||||||
ulint mysql_process_no;/* since in Linux, 'top' reports
|
ulint mysql_process_no;/* since in Linux, 'top' reports
|
||||||
|
@ -1854,6 +1854,7 @@ os_file_pread(
|
|||||||
return(n_bytes);
|
return(n_bytes);
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
off_t ret_offset;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
@ -1862,12 +1863,12 @@ os_file_pread(
|
|||||||
|
|
||||||
os_mutex_enter(os_file_seek_mutexes[i]);
|
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]);
|
os_mutex_exit(os_file_seek_mutexes[i]);
|
||||||
|
|
||||||
return(ret);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = read(file, buf, (ssize_t)n);
|
ret = read(file, buf, (ssize_t)n);
|
||||||
@ -1940,6 +1941,7 @@ os_file_pwrite(
|
|||||||
return(ret);
|
return(ret);
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
off_t ret_offset;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
/* Protect the seek / write operation with a mutex */
|
/* Protect the seek / write operation with a mutex */
|
||||||
@ -1947,12 +1949,12 @@ os_file_pwrite(
|
|||||||
|
|
||||||
os_mutex_enter(os_file_seek_mutexes[i]);
|
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]);
|
os_mutex_exit(os_file_seek_mutexes[i]);
|
||||||
|
|
||||||
return(ret);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = write(file, buf, (ssize_t)n);
|
ret = write(file, buf, (ssize_t)n);
|
||||||
|
@ -1187,7 +1187,7 @@ run_again:
|
|||||||
check_index = foreign->foreign_index;
|
check_index = foreign->foreign_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_table == NULL) {
|
if (check_table == NULL || check_table->ibd_file_missing) {
|
||||||
if (check_ref) {
|
if (check_ref) {
|
||||||
FILE* ef = dict_foreign_err_file;
|
FILE* ef = dict_foreign_err_file;
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
@ -1206,7 +1206,7 @@ run_again:
|
|||||||
dtuple_print(ef, entry);
|
dtuple_print(ef, entry);
|
||||||
fputs("\nBut the parent table ", ef);
|
fputs("\nBut the parent table ", ef);
|
||||||
ut_print_name(ef, trx, foreign->referenced_table_name);
|
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);
|
mutex_exit(&dict_foreign_err_mutex);
|
||||||
|
|
||||||
err = DB_NO_REFERENCED_ROW;
|
err = DB_NO_REFERENCED_ROW;
|
||||||
@ -1437,8 +1437,34 @@ row_ins_check_foreign_constraints(
|
|||||||
row_mysql_freeze_data_dictionary(trx);
|
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,
|
err = row_ins_check_foreign_constraint(TRUE, foreign,
|
||||||
table, entry, thr);
|
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) {
|
if (got_s_lock) {
|
||||||
row_mysql_unfreeze_data_dictionary(trx);
|
row_mysql_unfreeze_data_dictionary(trx);
|
||||||
}
|
}
|
||||||
|
@ -875,7 +875,21 @@ row_insert_for_mysql(
|
|||||||
|
|
||||||
ut_ad(trx);
|
ut_ad(trx);
|
||||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
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) {
|
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Error: trying to free a corrupt\n"
|
"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_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||||
UT_NOT_USED(mysql_rec);
|
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) {
|
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Error: trying to free a corrupt\n"
|
"InnoDB: Error: trying to free a corrupt\n"
|
||||||
@ -1865,20 +1893,19 @@ row_drop_table_for_mysql_in_background(
|
|||||||
|
|
||||||
trx = trx_allocate_for_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);
|
/* fputs("InnoDB: Error: Dropping table ", stderr);
|
||||||
ut_print_name(stderr, name);
|
ut_print_name(stderr, name);
|
||||||
fputs(" in background drop list\n", stderr); */
|
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);
|
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
|
/* Flush the log to reduce probability that the .frm files and
|
||||||
the InnoDB data dictionary get out-of-sync if the user runs
|
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);
|
trx_free_for_background(trx);
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@ -1924,6 +1951,7 @@ loop:
|
|||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
if (drop == NULL) {
|
if (drop == NULL) {
|
||||||
|
/* All tables dropped */
|
||||||
|
|
||||||
return(n_tables + n_tables_dropped);
|
return(n_tables + n_tables_dropped);
|
||||||
}
|
}
|
||||||
@ -1938,16 +1966,16 @@ loop:
|
|||||||
|
|
||||||
goto already_dropped;
|
goto already_dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->n_mysql_handles_opened > 0
|
if (DB_SUCCESS != row_drop_table_for_mysql_in_background(
|
||||||
|| table->n_foreign_key_checks_running > 0) {
|
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);
|
return(n_tables + n_tables_dropped);
|
||||||
}
|
}
|
||||||
|
|
||||||
n_tables_dropped++;
|
n_tables_dropped++;
|
||||||
|
|
||||||
row_drop_table_for_mysql_in_background(drop->table_name);
|
|
||||||
|
|
||||||
already_dropped:
|
already_dropped:
|
||||||
mutex_enter(&kernel_mutex);
|
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
|
If a table is not yet in the drop list, adds the table to the list of tables
|
||||||
background. We need this on Unix because in ALTER TABLE MySQL may call
|
which the master thread drops in background. We need this on Unix because in
|
||||||
drop table even if the table has running queries on it. */
|
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
|
static
|
||||||
void
|
ibool
|
||||||
row_add_table_to_background_drop_list(
|
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 */
|
dict_table_t* table) /* in: table */
|
||||||
{
|
{
|
||||||
row_mysql_drop_t* drop;
|
row_mysql_drop_t* drop;
|
||||||
|
|
||||||
drop = mem_alloc(sizeof(row_mysql_drop_t));
|
|
||||||
|
|
||||||
drop->table_name = mem_strdup(table->name);
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
if (!row_mysql_drop_list_inited) {
|
if (!row_mysql_drop_list_inited) {
|
||||||
@ -2013,7 +2041,26 @@ row_add_table_to_background_drop_list(
|
|||||||
UT_LIST_INIT(row_mysql_drop_list);
|
UT_LIST_INIT(row_mysql_drop_list);
|
||||||
row_mysql_drop_list_inited = TRUE;
|
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);
|
UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);
|
||||||
|
|
||||||
/* fputs("InnoDB: Adding table ", stderr);
|
/* fputs("InnoDB: Adding table ", stderr);
|
||||||
@ -2021,14 +2068,32 @@ row_add_table_to_background_drop_list(
|
|||||||
fputs(" to background drop list\n", stderr); */
|
fputs(" to background drop list\n", stderr); */
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Discards the tablespace of a table which stored in an .ibd file. Discarding
|
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
|
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.
|
operations could try to access non-existent pages.
|
||||||
|
|
||||||
1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock
|
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
|
have the same id, but the tablespace_version field in the mem object is
|
||||||
different, and ongoing old insert buffer page merges get discarded.
|
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
|
4) Linear readahead and random readahead: we use the same method as in 3) to
|
||||||
discard ongoing operations. */
|
discard ongoing operations.
|
||||||
|
5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we
|
||||||
int
|
do not allow the discard. We also reserve the data dictionary latch. */
|
||||||
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;
|
|
||||||
|
|
||||||
static const char discard_tablespace_proc1[] =
|
static const char discard_tablespace_proc1[] =
|
||||||
"PROCEDURE DISCARD_TABLESPACE_PROC () IS\n"
|
"PROCEDURE DISCARD_TABLESPACE_PROC () IS\n"
|
||||||
@ -2120,6 +2172,54 @@ row_discard_tablespace_for_mysql(
|
|||||||
goto funct_exit;
|
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);
|
new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
|
||||||
|
|
||||||
buf = mem_alloc((sizeof discard_tablespace_proc1) +
|
buf = mem_alloc((sizeof discard_tablespace_proc1) +
|
||||||
@ -2137,6 +2237,10 @@ row_discard_tablespace_for_mysql(
|
|||||||
|
|
||||||
ut_a(graph);
|
ut_a(graph);
|
||||||
|
|
||||||
|
/* Remove any locks there are on the table or its records */
|
||||||
|
|
||||||
|
lock_reset_all_on_table(table);
|
||||||
|
|
||||||
graph->trx = trx;
|
graph->trx = trx;
|
||||||
trx->graph = NULL;
|
trx->graph = NULL;
|
||||||
|
|
||||||
@ -2287,8 +2391,8 @@ row_import_tablespace_for_mysql(
|
|||||||
|
|
||||||
ibuf_delete_for_discarded_space(table->space);
|
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) {
|
if (success) {
|
||||||
table->ibd_file_missing = FALSE;
|
table->ibd_file_missing = FALSE;
|
||||||
table->tablespace_discarded = FALSE;
|
table->tablespace_discarded = FALSE;
|
||||||
@ -2296,7 +2400,7 @@ row_import_tablespace_for_mysql(
|
|||||||
if (table->ibd_file_missing) {
|
if (table->ibd_file_missing) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fputs(
|
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);
|
"InnoDB: table ", stderr);
|
||||||
ut_print_name(stderr, trx, name);
|
ut_print_name(stderr, trx, name);
|
||||||
fputs("\n"
|
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
|
with one of the predefined magic table names, then this also stops printing
|
||||||
the corresponding monitor output by the master thread. */
|
the corresponding monitor output by the master thread. */
|
||||||
|
|
||||||
@ -2552,36 +2656,60 @@ row_drop_table_for_mysql(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (table->n_mysql_handles_opened > 0) {
|
if (table->n_mysql_handles_opened > 0) {
|
||||||
|
ibool added;
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
added = row_add_table_to_background_drop_list(table);
|
||||||
fputs(" InnoDB: Warning: MySQL is trying to drop table ",
|
|
||||||
stderr);
|
if (added) {
|
||||||
ut_print_name(stderr, trx, table->name);
|
ut_print_timestamp(stderr);
|
||||||
fputs("\n"
|
fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr);
|
||||||
"InnoDB: though there are still open handles to it.\n"
|
ut_print_name(stderr, trx, table->name);
|
||||||
"InnoDB: Adding the table to the background drop queue.\n",
|
fputs("\n"
|
||||||
|
"InnoDB: though there are still open handles to it.\n"
|
||||||
|
"InnoDB: Adding the table to the background drop queue.\n",
|
||||||
stderr);
|
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;
|
||||||
|
} else {
|
||||||
err = DB_SUCCESS;
|
/* The table is already in the background drop list */
|
||||||
|
err = DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
goto funct_exit;
|
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) {
|
if (table->n_foreign_key_checks_running > 0) {
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
ibool added;
|
||||||
fputs(" InnoDB: You are trying to drop table ", stderr);
|
|
||||||
ut_print_name(stderr, trx, table->name);
|
added = row_add_table_to_background_drop_list(table);
|
||||||
fputs("\n"
|
|
||||||
"InnoDB: though there is a foreign key check running on it.\n"
|
if (added) {
|
||||||
"InnoDB: Adding the table to the background drop queue.\n",
|
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);
|
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;
|
goto funct_exit;
|
||||||
}
|
}
|
||||||
@ -3349,6 +3477,20 @@ row_check_table_for_mysql(
|
|||||||
ulint ret = DB_SUCCESS;
|
ulint ret = DB_SUCCESS;
|
||||||
ulint old_isolation_level;
|
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";
|
prebuilt->trx->op_info = "checking table";
|
||||||
|
|
||||||
old_isolation_level = prebuilt->trx->isolation_level;
|
old_isolation_level = prebuilt->trx->isolation_level;
|
||||||
|
@ -2897,7 +2897,7 @@ row_search_for_mysql(
|
|||||||
/* out: DB_SUCCESS,
|
/* out: DB_SUCCESS,
|
||||||
DB_RECORD_NOT_FOUND,
|
DB_RECORD_NOT_FOUND,
|
||||||
DB_END_OF_INDEX, DB_DEADLOCK,
|
DB_END_OF_INDEX, DB_DEADLOCK,
|
||||||
DB_LOCK_TABLE_FULL,
|
DB_LOCK_TABLE_FULL, DB_CORRUPTION,
|
||||||
or DB_TOO_BIG_RECORD */
|
or DB_TOO_BIG_RECORD */
|
||||||
byte* buf, /* in/out: buffer for the fetched
|
byte* buf, /* in/out: buffer for the fetched
|
||||||
row in the MySQL format */
|
row in the MySQL format */
|
||||||
@ -2952,7 +2952,21 @@ row_search_for_mysql(
|
|||||||
|
|
||||||
ut_ad(index && pcur && search_tuple);
|
ut_ad(index && pcur && search_tuple);
|
||||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
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) {
|
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Error: trying to free a corrupt\n"
|
"InnoDB: Error: trying to free a corrupt\n"
|
||||||
|
@ -1378,14 +1378,39 @@ NetWare. */
|
|||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Since ibuf init is in dict_boot, and ibuf is needed
|
/* Since the insert buffer init is in dict_boot, and the
|
||||||
in any disk i/o, first call dict_boot */
|
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();
|
dict_boot();
|
||||||
trx_sys_init_at_db_start();
|
trx_sys_init_at_db_start();
|
||||||
|
|
||||||
/* The following needs trx lists which are initialized in
|
if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
|
||||||
trx_sys_init_at_db_start */
|
/* 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;
|
srv_startup_is_before_trx_rollback_phase = FALSE;
|
||||||
|
|
||||||
@ -1393,6 +1418,9 @@ NetWare. */
|
|||||||
system */
|
system */
|
||||||
fsp_header_get_free_limit(0);
|
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();
|
recv_recovery_from_checkpoint_finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1431,13 +1459,6 @@ NetWare. */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* UNIV_LOG_ARCHIVE */
|
#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) {
|
if (srv_measure_contention) {
|
||||||
/* os_thread_create(&test_measure_cont, NULL, thread_ids +
|
/* 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",
|
"InnoDB: the sum of data file sizes is %lu pages\n",
|
||||||
(ulong) tablespace_size_in_header,
|
(ulong) tablespace_size_in_header,
|
||||||
(ulong) sum_of_data_file_sizes);
|
(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
|
if (srv_auto_extend_last_data_file
|
||||||
@ -1515,6 +1551,18 @@ NetWare. */
|
|||||||
"InnoDB: the sum of data file sizes is only %lu pages\n",
|
"InnoDB: the sum of data file sizes is only %lu pages\n",
|
||||||
(ulong) tablespace_size_in_header,
|
(ulong) tablespace_size_in_header,
|
||||||
(ulong) sum_of_data_file_sizes);
|
(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 */
|
/* Check that os_fast_mutexes work as expected */
|
||||||
|
@ -110,6 +110,9 @@ trx_create(
|
|||||||
trx->mysql_log_offset = 0;
|
trx->mysql_log_offset = 0;
|
||||||
trx->mysql_master_log_file_name = "";
|
trx->mysql_master_log_file_name = "";
|
||||||
trx->mysql_master_log_pos = 0;
|
trx->mysql_master_log_pos = 0;
|
||||||
|
|
||||||
|
trx->repl_wait_binlog_name = NULL;
|
||||||
|
trx->repl_wait_binlog_pos = 0;
|
||||||
|
|
||||||
mutex_create(&(trx->undo_mutex));
|
mutex_create(&(trx->undo_mutex));
|
||||||
mutex_set_level(&(trx->undo_mutex), SYNC_TRX_UNDO);
|
mutex_set_level(&(trx->undo_mutex), SYNC_TRX_UNDO);
|
||||||
@ -277,6 +280,11 @@ trx_free(
|
|||||||
trx_undo_arr_free(trx->undo_no_arr);
|
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->signals) == 0);
|
||||||
ut_a(UT_LIST_GET_LEN(trx->reply_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;
|
uint new_len= (tocs->mbmaxlen * length) / fromcs->mbminlen + 1;
|
||||||
result= (char *)alloc_root(root, new_len);
|
result= (char *)alloc_root(root, new_len);
|
||||||
length= copy_and_convert(result, new_len,
|
length= copy_and_convert(result, new_len,
|
||||||
tocs, from, length, fromcs, &dummy_err);
|
tocs, from, length, fromcs, &dummy_err);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -645,15 +645,15 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
|
|||||||
item->make_field(&server_field);
|
item->make_field(&server_field);
|
||||||
|
|
||||||
client_field->db= dup_str_aux(field_alloc, server_field.db_name,
|
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,
|
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,
|
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,
|
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,
|
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)
|
if (item->collation.collation == &my_charset_bin || thd_cs == NULL)
|
||||||
{
|
{
|
||||||
/* No conversion */
|
/* 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_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_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"
|
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
|
export NDB_TOOLS_DIR
|
||||||
|
|
||||||
MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \
|
MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \
|
||||||
|
@ -31,12 +31,12 @@ QUIT Quit management client
|
|||||||
<id> = ALL | Any database node id
|
<id> = ALL | Any database node id
|
||||||
|
|
||||||
Connected to Management Server at: localhost:1186
|
Connected to Management Server at: localhost:1186
|
||||||
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)
|
||||||
|
|
||||||
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 1 OK!
|
||||||
Executing CLUSTERLOG on node 2 OK!
|
Executing CLUSTERLOG on node 2 OK!
|
||||||
|
@ -121,7 +121,7 @@ create database mysqltest;
|
|||||||
create table mysqltest.t1 (a int,b int,c int);
|
create table mysqltest.t1 (a int,b int,c int);
|
||||||
grant all on mysqltest.t1 to mysqltest_1@localhost;
|
grant all on mysqltest.t1 to mysqltest_1@localhost;
|
||||||
alter table t1 rename t2;
|
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;
|
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
|
||||||
delete from mysql.user where user=_binary'mysqltest_1';
|
delete from mysql.user where user=_binary'mysqltest_1';
|
||||||
drop database mysqltest;
|
drop database mysqltest;
|
||||||
|
@ -591,3 +591,14 @@ x,y 0078002C0079
|
|||||||
z 007A
|
z 007A
|
||||||
x,y,z,ä,ö,ü 0078002C0079002C007A002C00E4002C00F6002C00FC
|
x,y,z,ä,ö,ü 0078002C0079002C007A002C00E4002C00F6002C00FC
|
||||||
drop table t1;
|
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-2001 %d-%m-%Y %H:%i:%S 00:00:00
|
||||||
15-01-20 %d-%m-%y 00:00:00
|
15-01-20 %d-%m-%y 00:00:00
|
||||||
15-2001-1 %d-%Y-%c 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;
|
truncate table t1;
|
||||||
insert into t1 values
|
insert into t1 values
|
||||||
('2003-01-02 10:11:12 PM', '%Y-%m-%d %H:%i:%S %p'),
|
('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);
|
select 'a' union select concat('a', -0.0);
|
||||||
a
|
a
|
||||||
a
|
a
|
||||||
a-0.0
|
a0.0
|
||||||
select 'a' union select concat('a', -0.0000);
|
select 'a' union select concat('a', -0.0000);
|
||||||
a
|
a
|
||||||
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
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select degrees(pi()) AS `degrees(pi())`,radians(360) AS `radians(360)`
|
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
|
total reg
|
||||||
10 2004-12-10
|
10 2004-12-10
|
||||||
drop table t1;
|
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'
|
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';
|
delete from mysql.user where user='mysqltest_1';
|
||||||
flush privileges;
|
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;
|
grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost;
|
||||||
show grants for mysqltest_1@localhost;
|
show grants for mysqltest_1@localhost;
|
||||||
Grants for mysqltest_1@localhost
|
Grants for mysqltest_1@localhost
|
||||||
|
@ -45,7 +45,6 @@ show grants for current_user();
|
|||||||
Grants for mysqltest_1@localhost
|
Grants for mysqltest_1@localhost
|
||||||
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
||||||
GRANT SELECT, INSERT ON `mysqltest`.* 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!');
|
insert into t1 values (1, 'I can''t change it!');
|
||||||
update t1 set data='I can change it!' where id = 1;
|
update t1 set data='I can change it!' where id = 1;
|
||||||
ERROR 42000: update command denied to user 'mysqltest_1'@'localhost' for table 't1'
|
ERROR 42000: update command denied to user 'mysqltest_1'@'localhost' for table 't1'
|
||||||
@ -55,8 +54,6 @@ select * from t1;
|
|||||||
id data
|
id data
|
||||||
1 I can't change it!
|
1 I can't change it!
|
||||||
drop table t1;
|
drop table t1;
|
||||||
drop database mysqltest;
|
|
||||||
use test;
|
|
||||||
delete from mysql.user where user like 'mysqltest\_%';
|
delete from mysql.user where user like 'mysqltest\_%';
|
||||||
delete from mysql.db where user like 'mysqltest\_%';
|
delete from mysql.db where user like 'mysqltest\_%';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
@ -222,3 +219,17 @@ drop user mysqltest_B@'%';
|
|||||||
ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql'
|
ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql'
|
||||||
drop user mysqltest_B@'%';
|
drop user mysqltest_B@'%';
|
||||||
drop user mysqltest_3@localhost;
|
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
|
1 1 1 test.t1
|
||||||
2 2 2 test.t1
|
2 2 2 test.t1
|
||||||
select * from t2;
|
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";
|
show status like "Qcache_queries_in_cache";
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
Qcache_queries_in_cache 6
|
Qcache_queries_in_cache 6
|
||||||
@ -148,7 +148,7 @@ select "user3";
|
|||||||
user3
|
user3
|
||||||
user3
|
user3
|
||||||
select * from t1;
|
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;
|
select a from t1;
|
||||||
a
|
a
|
||||||
1
|
1
|
||||||
@ -156,7 +156,7 @@ a
|
|||||||
select c from t1;
|
select c from t1;
|
||||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1'
|
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1'
|
||||||
select * from t2;
|
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;
|
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'
|
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1'
|
||||||
show status like "Qcache_queries_in_cache";
|
show status like "Qcache_queries_in_cache";
|
||||||
|
@ -677,4 +677,9 @@ a b c
|
|||||||
1 2 0
|
1 2 0
|
||||||
1 1 1
|
1 1 1
|
||||||
1 1 0
|
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;
|
drop table t1, t2, t3;
|
||||||
|
@ -387,6 +387,7 @@ USE `test`;
|
|||||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
|
|
||||||
|
drop database mysqldump_test_db;
|
||||||
create database mysqldump_test_db character set latin2 collate latin2_bin;
|
create database mysqldump_test_db character set latin2 collate latin2_bin;
|
||||||
|
|
||||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
@ -409,3 +410,143 @@ USE `mysqldump_test_db`;
|
|||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
|
|
||||||
drop database mysqldump_test_db;
|
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
|
1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
2 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
|
2 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
|
||||||
drop table t1;
|
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
|
my_col
|
||||||
1
|
1
|
||||||
select a as my_col from t1;
|
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
|
grant select on mysqltest.t1 to second_user@localhost
|
||||||
identified by 'looser' ;
|
identified by 'looser' ;
|
||||||
show grants for second_user@localhost ;
|
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 USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
|
||||||
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
|
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
|
||||||
execute s_t1 ;
|
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 ;
|
revoke all privileges, grant option from second_user@localhost ;
|
||||||
show grants for second_user@localhost ;
|
show grants for second_user@localhost ;
|
||||||
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
|
s1
|
||||||
tttt
|
tttt
|
||||||
drop table t1;
|
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));
|
create table t2 (s1 char(5), index s1(s1));
|
||||||
insert into t1 values ('a1'),('a2'),('a3');
|
insert into t1 values ('a1'),('a2'),('a3');
|
||||||
insert into t2 values ('a1'),('a2');
|
insert into t2 values ('a1'),('a2');
|
||||||
@ -1459,25 +1459,25 @@ a2 1
|
|||||||
a3 1
|
a3 1
|
||||||
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
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
|
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
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
Warnings:
|
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`
|
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;
|
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
|
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
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
Warnings:
|
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`
|
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;
|
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
|
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
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
Warnings:
|
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`
|
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;
|
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
|
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
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 1 Using index; Using where
|
||||||
Warnings:
|
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`
|
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
|
c
|
||||||
Oceania
|
Oceania
|
||||||
drop table t1;
|
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')
|
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);
|
where t1.a = t2.c and t2.d = (select max(d) from t2);
|
||||||
select * from mysql.time_zone_name;
|
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;
|
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.user where user like 'mysqltest\_%';
|
||||||
delete from mysql.db where user like 'mysqltest\_%';
|
delete from mysql.db where user like 'mysqltest\_%';
|
||||||
delete from mysql.tables_priv 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';
|
show variables like 'timed_mutexes';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
timed_mutexes OFF
|
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';
|
show local variables like 'storage_engine';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
storage_engine HEAP
|
storage_engine HEAP
|
||||||
show global variables like 'storage_engine';
|
show global variables like 'storage_engine';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
storage_engine InnoDB
|
storage_engine MERGE
|
||||||
set GLOBAL query_cache_size=100000;
|
set GLOBAL query_cache_size=100000;
|
||||||
set GLOBAL myisam_max_sort_file_size=2000000;
|
set GLOBAL myisam_max_sort_file_size=2000000;
|
||||||
show global variables like 'myisam_max_sort_file_size';
|
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'
|
ERROR 42000: Incorrect argument type to variable 'max_join_size'
|
||||||
set storage_engine=UNKNOWN_TABLE_TYPE;
|
set storage_engine=UNKNOWN_TABLE_TYPE;
|
||||||
ERROR 42000: Unknown table 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'
|
ERROR 42000: Variable 'big_tables' can't be set to the value of '2'
|
||||||
show local variables like 'storage_engine';
|
show local variables like 'storage_engine';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
|
@ -376,3 +376,13 @@ insert into t1 values ('x,y');
|
|||||||
insert into t1 values ('x,y,z,Ä,Ö,Ü');
|
insert into t1 values ('x,y,z,Ä,Ö,Ü');
|
||||||
select a, hex(a) from t1 order by a;
|
select a, hex(a) from t1 order by a;
|
||||||
drop table t1;
|
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,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,TIME(str_to_date(date, format)) as time from t1;
|
||||||
select date,format,concat(TIME(str_to_date(date, format))) as time2 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
|
# Test wrong dates or converion specifiers
|
||||||
|
|
||||||
|
@ -51,3 +51,10 @@ SELECT ASIN(1.2-0.2);
|
|||||||
#select floor(log(16)/log(2));
|
#select floor(log(16)/log(2));
|
||||||
|
|
||||||
explain extended select degrees(pi()),radians(360);
|
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');
|
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;
|
select count(*) as total, left(c,10) as reg from t1 group by reg order by reg desc limit 0,12;
|
||||||
drop table t1;
|
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';
|
delete from mysql.user where user='mysqltest_1';
|
||||||
flush privileges;
|
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
|
# Test that the new db privileges are stored/retrieved correctly
|
||||||
#
|
#
|
||||||
|
@ -59,10 +59,9 @@ flush privileges;
|
|||||||
use mysqltest;
|
use mysqltest;
|
||||||
create table t1 (id int primary key, data varchar(255));
|
create table t1 (id int primary key, data varchar(255));
|
||||||
|
|
||||||
connect (mrbad, localhost, mysqltest_1,,);
|
connect (mrbad, localhost, mysqltest_1,,mysqltest);
|
||||||
connection mrbad;
|
connection mrbad;
|
||||||
show grants for current_user();
|
show grants for current_user();
|
||||||
use mysqltest;
|
|
||||||
insert into t1 values (1, 'I can''t change it!');
|
insert into t1 values (1, 'I can''t change it!');
|
||||||
--error 1142
|
--error 1142
|
||||||
update t1 set data='I can change it!' where id = 1;
|
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
|
--error 1142
|
||||||
insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!';
|
insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!';
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
disconnect mrbad;
|
||||||
|
|
||||||
connection default;
|
connection default;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
drop database mysqltest;
|
|
||||||
use test;
|
|
||||||
delete from mysql.user where user like 'mysqltest\_%';
|
delete from mysql.user where user like 'mysqltest\_%';
|
||||||
delete from mysql.db where user like 'mysqltest\_%';
|
delete from mysql.db where user like 'mysqltest\_%';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
@ -226,4 +224,26 @@ connection default;
|
|||||||
drop user mysqltest_B@'%';
|
drop user mysqltest_B@'%';
|
||||||
drop user mysqltest_3@localhost;
|
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;
|
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;
|
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;
|
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;
|
drop table t1,t2;
|
||||||
|
|
||||||
# Test for BUG#5837 - delete with outer join and const tables
|
# Test for BUG#5837 - delete with outer join and const tables
|
||||||
|
--disable_warnings
|
||||||
create table t1 (
|
create table t1 (
|
||||||
aclid bigint not null primary key,
|
aclid bigint not null primary key,
|
||||||
status tinyint(1) not null
|
status tinyint(1) not null
|
||||||
@ -443,6 +444,7 @@ create table t2 (
|
|||||||
refid bigint not null primary key,
|
refid bigint not null primary key,
|
||||||
aclid bigint, index idx_acl(aclid)
|
aclid bigint, index idx_acl(aclid)
|
||||||
) engine = innodb;
|
) engine = innodb;
|
||||||
|
--enable_warnings
|
||||||
insert into t2 values(1,null);
|
insert into t2 values(1,null);
|
||||||
delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1';
|
delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1';
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
@ -146,3 +146,31 @@ drop table t1;
|
|||||||
create database mysqldump_test_db character set latin2 collate latin2_bin;
|
create database mysqldump_test_db character set latin2 collate latin2_bin;
|
||||||
--exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db;
|
--exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db;
|
||||||
drop database 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;
|
alter table t1 engine=myisam;
|
||||||
select * from t1 order by a;
|
select * from t1 order by a;
|
||||||
drop table t1;
|
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
|
# 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));
|
create table t2 (s1 char(5), index s1(s1));
|
||||||
insert into t1 values ('a1'),('a2'),('a3');
|
insert into t1 values ('a1'),('a2'),('a3');
|
||||||
insert into t2 values ('a1'),('a2');
|
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 */;
|
/*!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);
|
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
||||||
drop table t1;
|
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';
|
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 local variables like 'storage_engine';
|
||||||
show global variables like 'storage_engine';
|
show global variables like 'storage_engine';
|
||||||
set GLOBAL query_cache_size=100000;
|
set GLOBAL query_cache_size=100000;
|
||||||
@ -146,7 +146,7 @@ set max_join_size="hello";
|
|||||||
--error 1286
|
--error 1286
|
||||||
set storage_engine=UNKNOWN_TABLE_TYPE;
|
set storage_engine=UNKNOWN_TABLE_TYPE;
|
||||||
--error 1231
|
--error 1231
|
||||||
set storage_engine=INNODB, big_tables=2;
|
set storage_engine=MERGE, big_tables=2;
|
||||||
show local variables like 'storage_engine';
|
show local variables like 'storage_engine';
|
||||||
--error 1229
|
--error 1229
|
||||||
set SESSION query_cache_size=10000;
|
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)/mysys/libmysys.a \
|
||||||
$(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
|
$(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 \
|
||||||
-I$(top_srcdir)/ndb/include/ndbapi \
|
-I$(top_srcdir)/ndb/include/ndbapi \
|
||||||
-I$(top_srcdir)/ndb/include/util \
|
-I$(top_srcdir)/ndb/include/util \
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
include $(top_srcdir)/ndb/config/common.mk.am
|
include $(top_srcdir)/ndb/config/common.mk.am
|
||||||
|
|
||||||
ndbinclude_HEADERS = \
|
ndbinclude_HEADERS = \
|
||||||
|
ndb_init.h \
|
||||||
ndb_types.h \
|
ndb_types.h \
|
||||||
ndb_version.h
|
ndb_version.h
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "Logger.hpp"
|
#include "Logger.hpp"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the base class for all log handlers. A log handler is
|
* 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.
|
* 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 a log message to the output stream/file whatever.
|
||||||
* append() will call writeHeader(), writeMessage() and writeFooter() for
|
* 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 pCategory the category/name to tag the log entry with.
|
||||||
* @param level the log level.
|
* @param level the log level.
|
||||||
@ -76,6 +76,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
void append(const char* pCategory, Logger::LoggerLevel level,
|
void append(const char* pCategory, Logger::LoggerLevel level,
|
||||||
const char* pMsg);
|
const char* pMsg);
|
||||||
|
void append_impl(const char* pCategory, Logger::LoggerLevel level,
|
||||||
|
const char* pMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a default formatted header. It currently has the
|
* Returns a default formatted header. It currently has the
|
||||||
@ -111,14 +113,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setDateTimeFormat(const char* pFormat);
|
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.
|
* Returns the error code.
|
||||||
*/
|
*/
|
||||||
@ -185,6 +179,15 @@ protected:
|
|||||||
virtual void writeFooter() = 0;
|
virtual void writeFooter() = 0;
|
||||||
|
|
||||||
private:
|
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 */
|
/** Prohibit */
|
||||||
LogHandler(const LogHandler&);
|
LogHandler(const LogHandler&);
|
||||||
LogHandler* operator = (const LogHandler&);
|
LogHandler* operator = (const LogHandler&);
|
||||||
@ -192,6 +195,14 @@ private:
|
|||||||
|
|
||||||
const char* m_pDateTimeFormat;
|
const char* m_pDateTimeFormat;
|
||||||
int m_errorCode;
|
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
|
#endif
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include <ndb_global.h>
|
#include <ndb_global.h>
|
||||||
#include <BaseString.hpp>
|
#include <BaseString.hpp>
|
||||||
|
|
||||||
|
#define MAX_LOG_MESSAGE_SIZE 1024
|
||||||
|
|
||||||
class LogHandler;
|
class LogHandler;
|
||||||
class LogHandlerList;
|
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
|
#ifndef NDBGLOBAL_H
|
||||||
#define NDBGLOBAL_H
|
#define NDBGLOBAL_H
|
||||||
@ -96,15 +111,12 @@ extern "C" {
|
|||||||
|
|
||||||
#include <assert.h>
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "ndb_init.h"
|
||||||
|
|
||||||
#ifdef SCO
|
#ifdef SCO
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
#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
|
#ifndef NdbApi_H
|
||||||
#define NdbApi_H
|
#define NdbApi_H
|
||||||
|
|
||||||
|
#include "ndb_init.h"
|
||||||
|
#include "ndb_cluster_connection.hpp"
|
||||||
#include "ndbapi_limits.h"
|
#include "ndbapi_limits.h"
|
||||||
#include "Ndb.hpp"
|
#include "Ndb.hpp"
|
||||||
#include "NdbConnection.hpp"
|
#include "NdbConnection.hpp"
|
||||||
|
@ -182,27 +182,12 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Get blob parts table name. Useful only to test programs.
|
* 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);
|
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
|
* Return error object. The error may be blob specific (below) or may
|
||||||
* be copied from a failed implicit operation.
|
* be copied from a failed implicit operation.
|
||||||
*/
|
*/
|
||||||
const NdbError& getNdbError() const;
|
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.
|
* Return info about all blobs in this operation.
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL // Not part of public interface
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL // Not part of public interface
|
||||||
|
|
||||||
#include <ndb_types.h>
|
#include <ndb_types.h>
|
||||||
#include <ndb_global.h>
|
|
||||||
|
|
||||||
class Ndb;
|
class Ndb;
|
||||||
class NdbConnection;
|
class NdbConnection;
|
||||||
@ -131,7 +130,9 @@ int
|
|||||||
NdbReceiver::execTCOPCONF(Uint32 len){
|
NdbReceiver::execTCOPCONF(Uint32 len){
|
||||||
Uint32 tmp = m_received_result_length;
|
Uint32 tmp = m_received_result_length;
|
||||||
m_expected_result_length = len;
|
m_expected_result_length = len;
|
||||||
|
#ifdef assert
|
||||||
assert(!(tmp && !len));
|
assert(!(tmp && !len));
|
||||||
|
#endif
|
||||||
return ((bool)len ^ (bool)tmp ? 0 : 1);
|
return ((bool)len ^ (bool)tmp ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,28 +18,72 @@
|
|||||||
#ifndef CLUSTER_CONNECTION_HPP
|
#ifndef CLUSTER_CONNECTION_HPP
|
||||||
#define 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 {
|
class Ndb_cluster_connection {
|
||||||
public:
|
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(const char * connect_string = 0);
|
||||||
~Ndb_cluster_connection();
|
~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
|
* Connect to a cluster management server
|
||||||
// timeout_after_first_alive positive - ok if some alive
|
*
|
||||||
|
* @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 wait_until_ready(int timeout_for_first_alive,
|
||||||
int timeout_after_first_alive);
|
int timeout_after_first_alive);
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
const char *get_connectstring(char *buf, int buf_sz) const;
|
const char *get_connectstring(char *buf, int buf_sz) const;
|
||||||
int get_connected_port() const;
|
int get_connected_port() const;
|
||||||
const char *get_connected_host() const;
|
const char *get_connected_host() const;
|
||||||
|
|
||||||
void set_optimized_node_selection(int val);
|
void set_optimized_node_selection(int val);
|
||||||
|
|
||||||
Uint32 no_db_nodes();
|
unsigned no_db_nodes();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Ndb;
|
friend class Ndb;
|
||||||
|
@ -68,6 +68,8 @@ struct TCP_TransporterConfiguration {
|
|||||||
*/
|
*/
|
||||||
struct SHM_TransporterConfiguration {
|
struct SHM_TransporterConfiguration {
|
||||||
Uint32 port;
|
Uint32 port;
|
||||||
|
const char *remoteHostName;
|
||||||
|
const char *localHostName;
|
||||||
NodeId remoteNodeId;
|
NodeId remoteNodeId;
|
||||||
NodeId localNodeId;
|
NodeId localNodeId;
|
||||||
bool checksum;
|
bool checksum;
|
||||||
|
@ -99,7 +99,12 @@ public:
|
|||||||
unsigned sizeOfLongSignalMemory = 100);
|
unsigned sizeOfLongSignalMemory = 100);
|
||||||
|
|
||||||
bool init(NodeId localNodeId);
|
bool init(NodeId localNodeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* after a connect from client, perform connection using correct transporter
|
||||||
|
*/
|
||||||
|
bool connect_server(NDB_SOCKET_TYPE sockfd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all transporters
|
* Remove all transporters
|
||||||
*/
|
*/
|
||||||
|
@ -34,7 +34,7 @@ OPT_NDB_OPTIMIZED_NODE_SELECTION
|
|||||||
|
|
||||||
#define OPT_NDB_CONNECTSTRING 'c'
|
#define OPT_NDB_CONNECTSTRING 'c'
|
||||||
|
|
||||||
#ifdef NDB_SHM_TRANSPORTER
|
#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
|
||||||
#define OPT_NDB_SHM_DEFAULT 1
|
#define OPT_NDB_SHM_DEFAULT 1
|
||||||
#else
|
#else
|
||||||
#define OPT_NDB_SHM_DEFAULT 0
|
#define OPT_NDB_SHM_DEFAULT 0
|
||||||
|
@ -24,7 +24,13 @@
|
|||||||
LogHandler::LogHandler() :
|
LogHandler::LogHandler() :
|
||||||
m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
|
m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
|
||||||
m_errorCode(0)
|
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()
|
LogHandler::~LogHandler()
|
||||||
@ -34,11 +40,53 @@ LogHandler::~LogHandler()
|
|||||||
void
|
void
|
||||||
LogHandler::append(const char* pCategory, Logger::LoggerLevel level,
|
LogHandler::append(const char* pCategory, Logger::LoggerLevel level,
|
||||||
const char* pMsg)
|
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);
|
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();
|
writeFooter();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
LogHandler::getDefaultHeader(char* pStr, const char* pCategory,
|
LogHandler::getDefaultHeader(char* pStr, const char* pCategory,
|
||||||
@ -76,12 +124,10 @@ char*
|
|||||||
LogHandler::getTimeAsString(char* pStr) const
|
LogHandler::getTimeAsString(char* pStr) const
|
||||||
{
|
{
|
||||||
struct tm* tm_now;
|
struct tm* tm_now;
|
||||||
time_t now;
|
|
||||||
now = ::time((time_t*)NULL);
|
|
||||||
#ifdef NDB_WIN32
|
#ifdef NDB_WIN32
|
||||||
tm_now = localtime(&now);
|
tm_now = localtime(&m_now);
|
||||||
#else
|
#else
|
||||||
tm_now = ::localtime(&now); //uses the "current" timezone
|
tm_now = ::localtime(&m_now); //uses the "current" timezone
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH,
|
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;
|
LogHandler* pHandler = NULL;
|
||||||
while ( (pHandler = m_pHandlerList->next()) != NULL)
|
while ( (pHandler = m_pHandlerList->next()) != NULL)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[MAX_LOG_MESSAGE_SIZE];
|
||||||
BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap);
|
BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap);
|
||||||
pHandler->append(m_pCategory, logLevel, buf);
|
pHandler->append(m_pCategory, logLevel, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -383,6 +383,8 @@ IPCConfig::configureTransporters(Uint32 nodeId,
|
|||||||
if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break;
|
if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break;
|
||||||
|
|
||||||
conf.port= server_port;
|
conf.port= server_port;
|
||||||
|
conf.localHostName = localHostName;
|
||||||
|
conf.remoteHostName = remoteHostName;
|
||||||
|
|
||||||
if(!tr.createTransporter(&conf)){
|
if(!tr.createTransporter(&conf)){
|
||||||
DBUG_PRINT("error", ("Failed to create SHM Transporter from %d to %d",
|
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_LIBADD = @ndb_transporter_opt_objs@
|
||||||
libtransporter_la_DEPENDENCIES = @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/common.mk.am
|
||||||
include $(top_srcdir)/ndb/config/type_util.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 chksm,
|
||||||
bool signalId,
|
bool signalId,
|
||||||
Uint32 reportFreq) :
|
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)
|
_remoteNodeId, 0, false, chksm, signalId)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("SCI_Transporter::SCI_Transporter");
|
DBUG_ENTER("SCI_Transporter::SCI_Transporter");
|
||||||
|
@ -38,7 +38,8 @@ SHM_Transporter::SHM_Transporter(TransporterRegistry &t_reg,
|
|||||||
bool signalId,
|
bool signalId,
|
||||||
key_t _shmKey,
|
key_t _shmKey,
|
||||||
Uint32 _shmSize) :
|
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),
|
0, false, checksum, signalId),
|
||||||
shmKey(_shmKey),
|
shmKey(_shmKey),
|
||||||
shmSize(_shmSize)
|
shmSize(_shmSize)
|
||||||
@ -256,6 +257,9 @@ SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
|
|||||||
SocketOutputStream s_output(sockfd);
|
SocketOutputStream s_output(sockfd);
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#endif
|
||||||
|
|
||||||
// Wait for server to create and attach
|
// Wait for server to create and attach
|
||||||
if (s_input.gets(buf, 256) == 0) {
|
if (s_input.gets(buf, 256) == 0) {
|
||||||
NDB_CLOSE_SOCKET(sockfd);
|
NDB_CLOSE_SOCKET(sockfd);
|
||||||
|
@ -72,7 +72,8 @@ TCP_Transporter::TCP_Transporter(TransporterRegistry &t_reg,
|
|||||||
NodeId rNodeId,
|
NodeId rNodeId,
|
||||||
bool chksm, bool signalId,
|
bool chksm, bool signalId,
|
||||||
Uint32 _reportFreq) :
|
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),
|
0, false, chksm, signalId),
|
||||||
m_sendBuffer(sendBufSize)
|
m_sendBuffer(sendBufSize)
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,11 @@
|
|||||||
#include <InputStream.hpp>
|
#include <InputStream.hpp>
|
||||||
#include <OutputStream.hpp>
|
#include <OutputStream.hpp>
|
||||||
|
|
||||||
|
#include <EventLogger.hpp>
|
||||||
|
extern EventLogger g_eventLogger;
|
||||||
|
|
||||||
Transporter::Transporter(TransporterRegistry &t_reg,
|
Transporter::Transporter(TransporterRegistry &t_reg,
|
||||||
|
TransporterType _type,
|
||||||
const char *lHostName,
|
const char *lHostName,
|
||||||
const char *rHostName,
|
const char *rHostName,
|
||||||
int r_port,
|
int r_port,
|
||||||
@ -35,8 +39,10 @@ Transporter::Transporter(TransporterRegistry &t_reg,
|
|||||||
: m_r_port(r_port), remoteNodeId(rNodeId), localNodeId(lNodeId),
|
: m_r_port(r_port), remoteNodeId(rNodeId), localNodeId(lNodeId),
|
||||||
isServer(lNodeId < rNodeId),
|
isServer(lNodeId < rNodeId),
|
||||||
m_packer(_signalId, _checksum),
|
m_packer(_signalId, _checksum),
|
||||||
|
m_type(_type),
|
||||||
m_transporter_registry(t_reg)
|
m_transporter_registry(t_reg)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("Transporter::Transporter");
|
||||||
if (rHostName && strlen(rHostName) > 0){
|
if (rHostName && strlen(rHostName) > 0){
|
||||||
strncpy(remoteHostName, rHostName, sizeof(remoteHostName));
|
strncpy(remoteHostName, rHostName, sizeof(remoteHostName));
|
||||||
Ndb_getInAddr(&remoteHostAddress, rHostName);
|
Ndb_getInAddr(&remoteHostAddress, rHostName);
|
||||||
@ -55,6 +61,11 @@ Transporter::Transporter(TransporterRegistry &t_reg,
|
|||||||
if (strlen(lHostName) > 0)
|
if (strlen(lHostName) > 0)
|
||||||
Ndb_getInAddr(&localHostAddress, lHostName);
|
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;
|
byteOrder = _byteorder;
|
||||||
compressionUsed = _compression;
|
compressionUsed = _compression;
|
||||||
checksumUsed = _checksum;
|
checksumUsed = _checksum;
|
||||||
@ -67,7 +78,9 @@ Transporter::Transporter(TransporterRegistry &t_reg,
|
|||||||
m_socket_client= 0;
|
m_socket_client= 0;
|
||||||
else
|
else
|
||||||
m_socket_client= new SocketClient(remoteHostName, r_port,
|
m_socket_client= new SocketClient(remoteHostName, r_port,
|
||||||
new SocketAuthSimple("ndbd", "ndbd passwd"));
|
new SocketAuthSimple("ndbd",
|
||||||
|
"ndbd passwd"));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transporter::~Transporter(){
|
Transporter::~Transporter(){
|
||||||
@ -77,8 +90,13 @@ Transporter::~Transporter(){
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
|
Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
|
||||||
|
// all initial negotiation is done in TransporterRegistry::connect_server
|
||||||
|
DBUG_ENTER("Transporter::connect_server");
|
||||||
|
|
||||||
if(m_connected)
|
if(m_connected)
|
||||||
return true; // TODO assert(0);
|
{
|
||||||
|
DBUG_RETURN(true); // TODO assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
bool res = connect_server_impl(sockfd);
|
bool res = connect_server_impl(sockfd);
|
||||||
if(res){
|
if(res){
|
||||||
@ -86,7 +104,7 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
|
|||||||
m_errorCount = 0;
|
m_errorCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -98,27 +116,60 @@ Transporter::connect_client() {
|
|||||||
if (sockfd == NDB_INVALID_SOCKET)
|
if (sockfd == NDB_INVALID_SOCKET)
|
||||||
return false;
|
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);
|
SocketOutputStream s_output(sockfd);
|
||||||
s_output.println("%d", localNodeId);
|
s_output.println("%d %d", localNodeId, m_type);
|
||||||
// get remote id
|
// get remote id
|
||||||
int nodeId;
|
int nodeId, remote_transporter_type= -1;
|
||||||
SocketInputStream s_input(sockfd);
|
SocketInputStream s_input(sockfd);
|
||||||
char buf[256];
|
char buf[256];
|
||||||
if (s_input.gets(buf, 256) == 0) {
|
if (s_input.gets(buf, 256) == 0) {
|
||||||
NDB_CLOSE_SOCKET(sockfd);
|
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);
|
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);
|
bool res = connect_client_impl(sockfd);
|
||||||
if(res){
|
if(res){
|
||||||
m_connected = true;
|
m_connected = true;
|
||||||
m_errorCount = 0;
|
m_errorCount = 0;
|
||||||
}
|
}
|
||||||
return res;
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
Transporter(TransporterRegistry &,
|
Transporter(TransporterRegistry &,
|
||||||
|
TransporterType,
|
||||||
const char *lHostName,
|
const char *lHostName,
|
||||||
const char *rHostName,
|
const char *rHostName,
|
||||||
int r_port,
|
int r_port,
|
||||||
@ -127,6 +128,7 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool m_connected; // Are we connected
|
bool m_connected; // Are we connected
|
||||||
|
TransporterType m_type;
|
||||||
|
|
||||||
TransporterRegistry &m_transporter_registry;
|
TransporterRegistry &m_transporter_registry;
|
||||||
void *get_callback_obj() { return m_transporter_registry.callbackObj; };
|
void *get_callback_obj() { return m_transporter_registry.callbackObj; };
|
||||||
@ -149,7 +151,7 @@ Transporter::getRemoteNodeId() const {
|
|||||||
inline
|
inline
|
||||||
NodeId
|
NodeId
|
||||||
Transporter::getLocalNodeId() const {
|
Transporter::getLocalNodeId() const {
|
||||||
return remoteNodeId;
|
return localNodeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
@ -47,6 +47,9 @@
|
|||||||
#include <InputStream.hpp>
|
#include <InputStream.hpp>
|
||||||
#include <OutputStream.hpp>
|
#include <OutputStream.hpp>
|
||||||
|
|
||||||
|
#include <EventLogger.hpp>
|
||||||
|
extern EventLogger g_eventLogger;
|
||||||
|
|
||||||
int g_shm_pid = 0;
|
int g_shm_pid = 0;
|
||||||
|
|
||||||
SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd)
|
SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd)
|
||||||
@ -57,49 +60,10 @@ SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_transporter_registry->connect_server(sockfd))
|
||||||
{
|
{
|
||||||
// read node id from client
|
NDB_CLOSE_SOCKET(sockfd);
|
||||||
int nodeId;
|
DBUG_RETURN(0);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -195,6 +159,91 @@ TransporterRegistry::init(NodeId nodeId) {
|
|||||||
return true;
|
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
|
bool
|
||||||
TransporterRegistry::createTransporter(TCP_TransporterConfiguration *config) {
|
TransporterRegistry::createTransporter(TCP_TransporterConfiguration *config) {
|
||||||
#ifdef NDB_TCP_TRANSPORTER
|
#ifdef NDB_TCP_TRANSPORTER
|
||||||
@ -358,8 +407,8 @@ TransporterRegistry::createTransporter(SHM_TransporterConfiguration *config) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
SHM_Transporter * t = new SHM_Transporter(*this,
|
SHM_Transporter * t = new SHM_Transporter(*this,
|
||||||
"localhost",
|
config->localHostName,
|
||||||
"localhost",
|
config->remoteHostName,
|
||||||
config->port,
|
config->port,
|
||||||
localNodeId,
|
localNodeId,
|
||||||
config->remoteNodeId,
|
config->remoteNodeId,
|
||||||
|
@ -58,7 +58,7 @@ int main(int argc, char** argv)
|
|||||||
// Print to stdout/console
|
// Print to stdout/console
|
||||||
g_eventLogger.createConsoleHandler();
|
g_eventLogger.createConsoleHandler();
|
||||||
g_eventLogger.setCategory("NDB");
|
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();
|
globalEmulatorData.create();
|
||||||
|
|
||||||
|
@ -133,8 +133,7 @@ MgmtSrvr::signalRecvThreadRun()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern EventLogger g_eventLogger;
|
||||||
EventLogger g_EventLogger;
|
|
||||||
|
|
||||||
static NdbOut&
|
static NdbOut&
|
||||||
operator<<(NdbOut& out, const LogLevel & ll)
|
operator<<(NdbOut& out, const LogLevel & ll)
|
||||||
@ -200,7 +199,7 @@ MgmtSrvr::logLevelThreadRun()
|
|||||||
void
|
void
|
||||||
MgmtSrvr::startEventLog()
|
MgmtSrvr::startEventLog()
|
||||||
{
|
{
|
||||||
g_EventLogger.setCategory("MgmSrvr");
|
g_eventLogger.setCategory("MgmSrvr");
|
||||||
|
|
||||||
ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator
|
ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator
|
||||||
((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE);
|
((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE);
|
||||||
@ -226,7 +225,7 @@ MgmtSrvr::startEventLog()
|
|||||||
logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6",
|
logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6",
|
||||||
clusterLog);
|
clusterLog);
|
||||||
}
|
}
|
||||||
if(!g_EventLogger.addHandler(logdest)) {
|
if(!g_eventLogger.addHandler(logdest)) {
|
||||||
ndbout << "Warning: could not add log destination \""
|
ndbout << "Warning: could not add log destination \""
|
||||||
<< logdest.c_str() << "\"" << endl;
|
<< logdest.c_str() << "\"" << endl;
|
||||||
}
|
}
|
||||||
@ -250,21 +249,21 @@ MgmtSrvr::setEventLogFilter(int severity, int enable)
|
|||||||
{
|
{
|
||||||
Logger::LoggerLevel level = (Logger::LoggerLevel)severity;
|
Logger::LoggerLevel level = (Logger::LoggerLevel)severity;
|
||||||
if (enable > 0) {
|
if (enable > 0) {
|
||||||
g_EventLogger.enable(level);
|
g_eventLogger.enable(level);
|
||||||
} else if (enable == 0) {
|
} else if (enable == 0) {
|
||||||
g_EventLogger.disable(level);
|
g_eventLogger.disable(level);
|
||||||
} else if (g_EventLogger.isEnable(level)) {
|
} else if (g_eventLogger.isEnable(level)) {
|
||||||
g_EventLogger.disable(level);
|
g_eventLogger.disable(level);
|
||||||
} else {
|
} else {
|
||||||
g_EventLogger.enable(level);
|
g_eventLogger.enable(level);
|
||||||
}
|
}
|
||||||
return g_EventLogger.isEnable(level);
|
return g_eventLogger.isEnable(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MgmtSrvr::isEventLogFilterEnabled(int severity)
|
MgmtSrvr::isEventLogFilterEnabled(int severity)
|
||||||
{
|
{
|
||||||
return g_EventLogger.isEnable((Logger::LoggerLevel)severity);
|
return g_eventLogger.isEnable((Logger::LoggerLevel)severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ErrorItem errorTable[] =
|
static ErrorItem errorTable[] =
|
||||||
@ -1990,7 +1989,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_EventLogger.error("Unknown signal received. SignalNumber: "
|
g_eventLogger.error("Unknown signal received. SignalNumber: "
|
||||||
"%i from (%d, %x)",
|
"%i from (%d, %x)",
|
||||||
gsn,
|
gsn,
|
||||||
refToNode(signal->theSendersBlockRef),
|
refToNode(signal->theSendersBlockRef),
|
||||||
@ -2066,7 +2065,7 @@ MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
if(errCode != 0){
|
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);
|
GSN_STOP_REF, nodeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2286,7 +2285,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
|
|||||||
m_reserved_nodes.set(id_found);
|
m_reserved_nodes.set(id_found);
|
||||||
char tmp_str[128];
|
char tmp_str[128];
|
||||||
m_reserved_nodes.getText(tmp_str);
|
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);
|
id_found, get_connect_address(id_found), tmp_str);
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
@ -2346,7 +2345,7 @@ MgmtSrvr::alloc_node_id(NodeId * 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\"",
|
"Returned error string \"%s\"",
|
||||||
*nodeId,
|
*nodeId,
|
||||||
client_addr != 0 ? inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr) : "<none>",
|
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)
|
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());
|
tmp_connected.c_str());
|
||||||
if (tmp_not_connected.length() > 0)
|
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());
|
tmp_not_connected.c_str());
|
||||||
}
|
}
|
||||||
DBUG_RETURN(false);
|
DBUG_RETURN(false);
|
||||||
@ -2404,7 +2403,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
|
|||||||
|
|
||||||
EventReport::EventType type = eventReport->getEventType();
|
EventReport::EventType type = eventReport->getEventType();
|
||||||
// Log event
|
// Log event
|
||||||
g_EventLogger.log(type, theData, nodeId,
|
g_eventLogger.log(type, theData, nodeId,
|
||||||
&m_event_listner[0].m_logLevel);
|
&m_event_listner[0].m_logLevel);
|
||||||
m_event_listner.log(type, theData, nodeId);
|
m_event_listner.log(type, theData, nodeId);
|
||||||
}
|
}
|
||||||
@ -2647,7 +2646,7 @@ MgmtSrvr::Allocated_resources::~Allocated_resources()
|
|||||||
|
|
||||||
char tmp_str[128];
|
char tmp_str[128];
|
||||||
m_mgmsrv.m_reserved_nodes.getText(tmp_str);
|
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);
|
get_nodeid(), tmp_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ static MgmGlobals glob;
|
|||||||
* Global variables
|
* Global variables
|
||||||
*/
|
*/
|
||||||
bool g_StopServer;
|
bool g_StopServer;
|
||||||
extern EventLogger g_EventLogger;
|
extern EventLogger g_eventLogger;
|
||||||
|
|
||||||
extern int global_mgmt_server_check;
|
extern int global_mgmt_server_check;
|
||||||
|
|
||||||
@ -284,12 +284,12 @@ int main(int argc, char** argv)
|
|||||||
BaseString::snprintf(msg, sizeof(msg),
|
BaseString::snprintf(msg, sizeof(msg),
|
||||||
"NDB Cluster Management Server. %s", NDB_VERSION_STRING);
|
"NDB Cluster Management Server. %s", NDB_VERSION_STRING);
|
||||||
ndbout_c(msg);
|
ndbout_c(msg);
|
||||||
g_EventLogger.info(msg);
|
g_eventLogger.info(msg);
|
||||||
|
|
||||||
BaseString::snprintf(msg, 256, "Id: %d, Command port: %d",
|
BaseString::snprintf(msg, 256, "Id: %d, Command port: %d",
|
||||||
glob.localNodeId, glob.port);
|
glob.localNodeId, glob.port);
|
||||||
ndbout_c(msg);
|
ndbout_c(msg);
|
||||||
g_EventLogger.info(msg);
|
g_eventLogger.info(msg);
|
||||||
|
|
||||||
g_StopServer = false;
|
g_StopServer = false;
|
||||||
glob.socketServer->startServer();
|
glob.socketServer->startServer();
|
||||||
@ -305,10 +305,10 @@ int main(int argc, char** argv)
|
|||||||
NdbSleep_MilliSleep(500);
|
NdbSleep_MilliSleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_EventLogger.info("Shutting down server...");
|
g_eventLogger.info("Shutting down server...");
|
||||||
glob.socketServer->stopServer();
|
glob.socketServer->stopServer();
|
||||||
glob.socketServer->stopSessions();
|
glob.socketServer->stopSessions();
|
||||||
g_EventLogger.info("Shutdown complete");
|
g_eventLogger.info("Shutdown complete");
|
||||||
return 0;
|
return 0;
|
||||||
error_end:
|
error_end:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -282,7 +282,7 @@ Ndb::waitUntilReady(int timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (theImpl->m_ndb_cluster_connection.wait_until_ready
|
if (theImpl->m_ndb_cluster_connection.wait_until_ready
|
||||||
(timeout-secondsCounter,30))
|
(timeout-secondsCounter,30) < 0)
|
||||||
{
|
{
|
||||||
theError.code = 4009;
|
theError.code = 4009;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <NdbIndexOperation.hpp>
|
#include <NdbIndexOperation.hpp>
|
||||||
#include <NdbRecAttr.hpp>
|
#include <NdbRecAttr.hpp>
|
||||||
#include <NdbBlob.hpp>
|
#include <NdbBlob.hpp>
|
||||||
|
#include "NdbBlobImpl.hpp"
|
||||||
#include <NdbScanOperation.hpp>
|
#include <NdbScanOperation.hpp>
|
||||||
|
|
||||||
#ifdef NDB_BLOB_DEBUG
|
#ifdef NDB_BLOB_DEBUG
|
||||||
@ -85,14 +86,14 @@ void
|
|||||||
NdbBlob::getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c)
|
NdbBlob::getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c)
|
||||||
{
|
{
|
||||||
assert(t != 0 && c != 0 && c->getBlobType());
|
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);
|
sprintf(btname, "NDB$BLOB_%d_%d", (int)t->m_tableId, (int)c->m_attrId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c)
|
NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c)
|
||||||
{
|
{
|
||||||
char btname[BlobTableNameSize];
|
char btname[NdbBlobImpl::BlobTableNameSize];
|
||||||
getBlobTableName(btname, t, c);
|
getBlobTableName(btname, t, c);
|
||||||
bt.setName(btname);
|
bt.setName(btname);
|
||||||
bt.setLogging(t->getLogging());
|
bt.setLogging(t->getLogging());
|
||||||
@ -450,15 +451,15 @@ NdbBlob::getValue(void* data, Uint32 bytes)
|
|||||||
{
|
{
|
||||||
DBG("getValue data=" << hex << data << " bytes=" << dec << bytes);
|
DBG("getValue data=" << hex << data << " bytes=" << dec << bytes);
|
||||||
if (theGetFlag || theState != Prepared) {
|
if (theGetFlag || theState != Prepared) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (! isReadOp() && ! isScanOp()) {
|
if (! isReadOp() && ! isScanOp()) {
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (data == NULL && bytes != 0) {
|
if (data == NULL && bytes != 0) {
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
theGetFlag = true;
|
theGetFlag = true;
|
||||||
@ -472,15 +473,15 @@ NdbBlob::setValue(const void* data, Uint32 bytes)
|
|||||||
{
|
{
|
||||||
DBG("setValue data=" << hex << data << " bytes=" << dec << bytes);
|
DBG("setValue data=" << hex << data << " bytes=" << dec << bytes);
|
||||||
if (theSetFlag || theState != Prepared) {
|
if (theSetFlag || theState != Prepared) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (! isInsertOp() && ! isUpdateOp() && ! isWriteOp()) {
|
if (! isInsertOp() && ! isUpdateOp() && ! isWriteOp()) {
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (data == NULL && bytes != 0) {
|
if (data == NULL && bytes != 0) {
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
theSetFlag = true;
|
theSetFlag = true;
|
||||||
@ -512,7 +513,7 @@ NdbBlob::setActiveHook(ActiveHook activeHook, void* arg)
|
|||||||
{
|
{
|
||||||
DBG("setActiveHook hook=" << hex << (void*)activeHook << " arg=" << hex << arg);
|
DBG("setActiveHook hook=" << hex << (void*)activeHook << " arg=" << hex << arg);
|
||||||
if (theState != Prepared) {
|
if (theState != Prepared) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
theActiveHook = activeHook;
|
theActiveHook = activeHook;
|
||||||
@ -531,7 +532,7 @@ NdbBlob::getNull(bool& isNull)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (theNullFlag == -1) {
|
if (theNullFlag == -1) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
isNull = theNullFlag;
|
isNull = theNullFlag;
|
||||||
@ -546,7 +547,7 @@ NdbBlob::setNull()
|
|||||||
if (theState == Prepared) {
|
if (theState == Prepared) {
|
||||||
return setValue(0, 0);
|
return setValue(0, 0);
|
||||||
}
|
}
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (theNullFlag)
|
if (theNullFlag)
|
||||||
@ -568,7 +569,7 @@ NdbBlob::getLength(Uint64& len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (theNullFlag == -1) {
|
if (theNullFlag == -1) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
len = theLength;
|
len = theLength;
|
||||||
@ -580,7 +581,7 @@ NdbBlob::truncate(Uint64 length)
|
|||||||
{
|
{
|
||||||
DBG("truncate [in] length=" << length);
|
DBG("truncate [in] length=" << length);
|
||||||
if (theNullFlag == -1) {
|
if (theNullFlag == -1) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (theLength > length) {
|
if (theLength > length) {
|
||||||
@ -608,7 +609,7 @@ NdbBlob::getPos(Uint64& pos)
|
|||||||
{
|
{
|
||||||
DBG("getPos");
|
DBG("getPos");
|
||||||
if (theNullFlag == -1) {
|
if (theNullFlag == -1) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pos = thePos;
|
pos = thePos;
|
||||||
@ -620,11 +621,11 @@ NdbBlob::setPos(Uint64 pos)
|
|||||||
{
|
{
|
||||||
DBG("setPos pos=" << pos);
|
DBG("setPos pos=" << pos);
|
||||||
if (theNullFlag == -1) {
|
if (theNullFlag == -1) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (pos > theLength) {
|
if (pos > theLength) {
|
||||||
setErrorCode(ErrSeek);
|
setErrorCode(NdbBlobImpl::ErrSeek);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
thePos = pos;
|
thePos = pos;
|
||||||
@ -637,7 +638,7 @@ int
|
|||||||
NdbBlob::readData(void* data, Uint32& bytes)
|
NdbBlob::readData(void* data, Uint32& bytes)
|
||||||
{
|
{
|
||||||
if (theState != Active) {
|
if (theState != Active) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
char* buf = static_cast<char*>(data);
|
char* buf = static_cast<char*>(data);
|
||||||
@ -666,7 +667,7 @@ NdbBlob::readDataPrivate(char* buf, Uint32& bytes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len > 0 && thePartSize == 0) {
|
if (len > 0 && thePartSize == 0) {
|
||||||
setErrorCode(ErrSeek);
|
setErrorCode(NdbBlobImpl::ErrSeek);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
@ -731,7 +732,7 @@ int
|
|||||||
NdbBlob::writeData(const void* data, Uint32 bytes)
|
NdbBlob::writeData(const void* data, Uint32 bytes)
|
||||||
{
|
{
|
||||||
if (theState != Active) {
|
if (theState != Active) {
|
||||||
setErrorCode(ErrState);
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
const char* buf = static_cast<const char*>(data);
|
const char* buf = static_cast<const char*>(data);
|
||||||
@ -764,7 +765,7 @@ NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len > 0 && thePartSize == 0) {
|
if (len > 0 && thePartSize == 0) {
|
||||||
setErrorCode(ErrSeek);
|
setErrorCode(NdbBlobImpl::ErrSeek);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
@ -1081,7 +1082,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||||||
theFillChar = 0x20;
|
theFillChar = 0x20;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// sizes
|
// sizes
|
||||||
@ -1099,7 +1100,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||||||
(bc = bt->getColumn("DATA")) == NULL ||
|
(bc = bt->getColumn("DATA")) == NULL ||
|
||||||
bc->getType() != partType ||
|
bc->getType() != partType ||
|
||||||
bc->getLength() != (int)thePartSize) {
|
bc->getLength() != (int)thePartSize) {
|
||||||
setErrorCode(ErrTable);
|
setErrorCode(NdbBlobImpl::ErrTable);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
theBlobTable = &NdbTableImpl::getImpl(*bt);
|
theBlobTable = &NdbTableImpl::getImpl(*bt);
|
||||||
@ -1120,7 +1121,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||||||
Uint32* data = (Uint32*)theKeyBuf.data;
|
Uint32* data = (Uint32*)theKeyBuf.data;
|
||||||
unsigned size = theTable->m_keyLenInWords;
|
unsigned size = theTable->m_keyLenInWords;
|
||||||
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
|
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1129,7 +1130,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||||||
Uint32* data = (Uint32*)theAccessKeyBuf.data;
|
Uint32* data = (Uint32*)theAccessKeyBuf.data;
|
||||||
unsigned size = theAccessTable->m_keyLenInWords;
|
unsigned size = theAccessTable->m_keyLenInWords;
|
||||||
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
|
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1158,7 +1159,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||||||
supportedOp = true;
|
supportedOp = true;
|
||||||
}
|
}
|
||||||
if (! supportedOp) {
|
if (! supportedOp) {
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
setState(Prepared);
|
setState(Prepared);
|
||||||
@ -1204,7 +1205,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
|||||||
tOp->updateTuple() == -1 ||
|
tOp->updateTuple() == -1 ||
|
||||||
setTableKeyValue(tOp) == -1 ||
|
setTableKeyValue(tOp) == -1 ||
|
||||||
setHeadInlineValue(tOp) == -1) {
|
setHeadInlineValue(tOp) == -1) {
|
||||||
setErrorCode(ErrAbort);
|
setErrorCode(NdbBlobImpl::ErrAbort);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
DBG("add op to update head+inline");
|
DBG("add op to update head+inline");
|
||||||
@ -1434,7 +1435,7 @@ NdbBlob::postExecute(ExecType anExecType)
|
|||||||
tOp->updateTuple() == -1 ||
|
tOp->updateTuple() == -1 ||
|
||||||
setTableKeyValue(tOp) == -1 ||
|
setTableKeyValue(tOp) == -1 ||
|
||||||
setHeadInlineValue(tOp) == -1) {
|
setHeadInlineValue(tOp) == -1) {
|
||||||
setErrorCode(ErrAbort);
|
setErrorCode(NdbBlobImpl::ErrAbort);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tOp->m_abortOption = AbortOnError;
|
tOp->m_abortOption = AbortOnError;
|
||||||
@ -1464,7 +1465,7 @@ NdbBlob::preCommit()
|
|||||||
tOp->updateTuple() == -1 ||
|
tOp->updateTuple() == -1 ||
|
||||||
setTableKeyValue(tOp) == -1 ||
|
setTableKeyValue(tOp) == -1 ||
|
||||||
setHeadInlineValue(tOp) == -1) {
|
setHeadInlineValue(tOp) == -1) {
|
||||||
setErrorCode(ErrAbort);
|
setErrorCode(NdbBlobImpl::ErrAbort);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tOp->m_abortOption = AbortOnError;
|
tOp->m_abortOption = AbortOnError;
|
||||||
@ -1489,7 +1490,7 @@ NdbBlob::atNextResult()
|
|||||||
{ Uint32* data = (Uint32*)theKeyBuf.data;
|
{ Uint32* data = (Uint32*)theKeyBuf.data;
|
||||||
unsigned size = theTable->m_keyLenInWords;
|
unsigned size = theTable->m_keyLenInWords;
|
||||||
if (((NdbScanOperation*)theNdbOp)->getKeyFromKEYINFO20(data, size) == -1) {
|
if (((NdbScanOperation*)theNdbOp)->getKeyFromKEYINFO20(data, size) == -1) {
|
||||||
setErrorCode(ErrUsage);
|
setErrorCode(NdbBlobImpl::ErrUsage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1545,7 +1546,7 @@ NdbBlob::setErrorCode(NdbOperation* anOp, bool invalidFlag)
|
|||||||
else if ((code = theNdb->theError.code) != 0)
|
else if ((code = theNdb->theError.code) != 0)
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
code = ErrUnknown;
|
code = NdbBlobImpl::ErrUnknown;
|
||||||
setErrorCode(code, invalidFlag);
|
setErrorCode(code, invalidFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1558,7 +1559,7 @@ NdbBlob::setErrorCode(NdbConnection* aCon, bool invalidFlag)
|
|||||||
else if ((code = theNdb->theError.code) != 0)
|
else if ((code = theNdb->theError.code) != 0)
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
code = ErrUnknown;
|
code = NdbBlobImpl::ErrUnknown;
|
||||||
setErrorCode(code, invalidFlag);
|
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)
|
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
#ifndef VM_TRACE
|
#ifdef ndb_api_crash_on_complex_blob_abort
|
||||||
// can happen in complex abort cases
|
|
||||||
theFirstOpInList = theLastOpInList = NULL;
|
|
||||||
#else
|
|
||||||
assert(theFirstOpInList == NULL && theLastOpInList == NULL);
|
assert(theFirstOpInList == NULL && theLastOpInList == NULL);
|
||||||
|
#else
|
||||||
|
theFirstOpInList = theLastOpInList = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,8 @@
|
|||||||
#include <AttributeList.hpp>
|
#include <AttributeList.hpp>
|
||||||
#include <NdbEventOperation.hpp>
|
#include <NdbEventOperation.hpp>
|
||||||
#include "NdbEventOperationImpl.hpp"
|
#include "NdbEventOperationImpl.hpp"
|
||||||
#include "NdbBlob.hpp"
|
#include <NdbBlob.hpp>
|
||||||
|
#include "NdbBlobImpl.hpp"
|
||||||
#include <AttributeHeader.hpp>
|
#include <AttributeHeader.hpp>
|
||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
|
|
||||||
@ -1381,7 +1382,7 @@ NdbDictionaryImpl::addBlobTables(NdbTableImpl &t)
|
|||||||
if (! c.getBlobType() || c.getPartSize() == 0)
|
if (! c.getBlobType() || c.getPartSize() == 0)
|
||||||
continue;
|
continue;
|
||||||
n--;
|
n--;
|
||||||
char btname[NdbBlob::BlobTableNameSize];
|
char btname[NdbBlobImpl::BlobTableNameSize];
|
||||||
NdbBlob::getBlobTableName(btname, &t, &c);
|
NdbBlob::getBlobTableName(btname, &t, &c);
|
||||||
// Save BLOB table handle
|
// Save BLOB table handle
|
||||||
NdbTableImpl * cachedBlobTable = getTable(btname);
|
NdbTableImpl * cachedBlobTable = getTable(btname);
|
||||||
@ -1789,7 +1790,7 @@ NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t)
|
|||||||
NdbColumnImpl & c = *t.m_columns[i];
|
NdbColumnImpl & c = *t.m_columns[i];
|
||||||
if (! c.getBlobType() || c.getPartSize() == 0)
|
if (! c.getBlobType() || c.getPartSize() == 0)
|
||||||
continue;
|
continue;
|
||||||
char btname[NdbBlob::BlobTableNameSize];
|
char btname[NdbBlobImpl::BlobTableNameSize];
|
||||||
NdbBlob::getBlobTableName(btname, &t, &c);
|
NdbBlob::getBlobTableName(btname, &t, &c);
|
||||||
if (dropTable(btname) != 0) {
|
if (dropTable(btname) != 0) {
|
||||||
if (m_error.code != 709){
|
if (m_error.code != 709){
|
||||||
|
@ -523,7 +523,9 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo,
|
|||||||
CHARSET_INFO* cs = tAttrInfo->m_cs;
|
CHARSET_INFO* cs = tAttrInfo->m_cs;
|
||||||
// invalid data can crash kernel
|
// invalid data can crash kernel
|
||||||
if (cs != NULL &&
|
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,
|
||||||
aValue + sizeInBytes,
|
aValue + sizeInBytes,
|
||||||
sizeInBytes) != sizeInBytes) {
|
sizeInBytes) != sizeInBytes) {
|
||||||
|
@ -15,21 +15,11 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************************************
|
#include <ndb_global.h>
|
||||||
Name: NdbOperationInt.C
|
#include <NdbOperation.hpp>
|
||||||
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 "NdbApiSignal.hpp"
|
#include "NdbApiSignal.hpp"
|
||||||
#include "NdbConnection.hpp"
|
#include <NdbConnection.hpp>
|
||||||
#include "Ndb.hpp"
|
#include <Ndb.hpp>
|
||||||
#include "NdbRecAttr.hpp"
|
#include "NdbRecAttr.hpp"
|
||||||
#include "NdbUtil.hpp"
|
#include "NdbUtil.hpp"
|
||||||
#include "Interpreter.hpp"
|
#include "Interpreter.hpp"
|
||||||
|
@ -204,14 +204,6 @@ Ndb::~Ndb()
|
|||||||
TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId);
|
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)
|
// if (theSchemaConToNdbList != NULL)
|
||||||
// closeSchemaTransaction(theSchemaConToNdbList);
|
// closeSchemaTransaction(theSchemaConToNdbList);
|
||||||
while ( theConIdleList != NULL )
|
while ( theConIdleList != NULL )
|
||||||
@ -249,6 +241,19 @@ Ndb::~Ndb()
|
|||||||
|
|
||||||
delete theImpl;
|
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
|
* This sleep is to make sure that the transporter
|
||||||
* send thread will come in and send any
|
* send thread will come in and send any
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
#include <Vector.hpp>
|
#include <Vector.hpp>
|
||||||
#include <md5_hash.hpp>
|
#include <md5_hash.hpp>
|
||||||
|
|
||||||
|
#include <EventLogger.hpp>
|
||||||
|
EventLogger g_eventLogger;
|
||||||
|
|
||||||
static int g_run_connect_thread= 0;
|
static int g_run_connect_thread= 0;
|
||||||
|
|
||||||
#include <NdbMutex.h>
|
#include <NdbMutex.h>
|
||||||
@ -174,7 +177,7 @@ Ndb_cluster_connection_impl::get_next_node(Ndb_cluster_connection_node_iter &ite
|
|||||||
return node.id;
|
return node.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32
|
unsigned
|
||||||
Ndb_cluster_connection::no_db_nodes()
|
Ndb_cluster_connection::no_db_nodes()
|
||||||
{
|
{
|
||||||
return m_impl.m_all_nodes.size();
|
return m_impl.m_all_nodes.size();
|
||||||
@ -219,16 +222,8 @@ Ndb_cluster_connection::wait_until_ready(int timeout,
|
|||||||
else if (foundAliveNode > 0)
|
else if (foundAliveNode > 0)
|
||||||
{
|
{
|
||||||
noChecksSinceFirstAliveFound++;
|
noChecksSinceFirstAliveFound++;
|
||||||
if (timeout_after_first_alive >= 0)
|
if (noChecksSinceFirstAliveFound > timeout_after_first_alive)
|
||||||
{
|
DBUG_RETURN(1);
|
||||||
if (noChecksSinceFirstAliveFound > timeout_after_first_alive)
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
else // timeout_after_first_alive < 0
|
|
||||||
{
|
|
||||||
if (noChecksSinceFirstAliveFound > -timeout_after_first_alive)
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (secondsCounter >= timeout)
|
else if (secondsCounter >= timeout)
|
||||||
{ // no alive nodes and timed out
|
{ // 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_ENTER("Ndb_cluster_connection");
|
||||||
DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this));
|
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=
|
m_transporter_facade=
|
||||||
TransporterFacade::theFacadeInstance= new TransporterFacade();
|
TransporterFacade::theFacadeInstance= new TransporterFacade();
|
||||||
|
|
||||||
|
@ -23,13 +23,14 @@
|
|||||||
#include <NdbOut.hpp>
|
#include <NdbOut.hpp>
|
||||||
#include <NdbTest.hpp>
|
#include <NdbTest.hpp>
|
||||||
#include <NdbTick.h>
|
#include <NdbTick.h>
|
||||||
|
#include <ndb/src/ndbapi/NdbBlobImpl.hpp>
|
||||||
|
|
||||||
struct Bcol {
|
struct Bcol {
|
||||||
bool m_nullable;
|
bool m_nullable;
|
||||||
unsigned m_inline;
|
unsigned m_inline;
|
||||||
unsigned m_partsize;
|
unsigned m_partsize;
|
||||||
unsigned m_stripe;
|
unsigned m_stripe;
|
||||||
char m_btname[NdbBlob::BlobTableNameSize];
|
char m_btname[NdbBlobImpl::BlobTableNameSize];
|
||||||
Bcol(bool a, unsigned b, unsigned c, unsigned d) :
|
Bcol(bool a, unsigned b, unsigned c, unsigned d) :
|
||||||
m_nullable(a),
|
m_nullable(a),
|
||||||
m_inline(b),
|
m_inline(b),
|
||||||
@ -153,6 +154,7 @@ testcase(char x)
|
|||||||
(g_opt.m_skip == 0 || strchr(g_opt.m_skip, x) == 0);
|
(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 Ndb* g_ndb = 0;
|
||||||
static NdbDictionary::Dictionary* g_dic = 0;
|
static NdbDictionary::Dictionary* g_dic = 0;
|
||||||
static NdbConnection* g_con = 0;
|
static NdbConnection* g_con = 0;
|
||||||
@ -1258,7 +1260,7 @@ deleteScan(bool idx)
|
|||||||
static int
|
static int
|
||||||
testmain()
|
testmain()
|
||||||
{
|
{
|
||||||
g_ndb = new Ndb("TEST_DB");
|
g_ndb = new Ndb(g_ncc, "TEST_DB");
|
||||||
CHK(g_ndb->init() == 0);
|
CHK(g_ndb->init() == 0);
|
||||||
CHK(g_ndb->waitUntilReady() == 0);
|
CHK(g_ndb->waitUntilReady() == 0);
|
||||||
g_dic = g_ndb->getDictionary();
|
g_dic = g_ndb->getDictionary();
|
||||||
@ -1447,7 +1449,7 @@ testperf()
|
|||||||
if (! testcase('p'))
|
if (! testcase('p'))
|
||||||
return 0;
|
return 0;
|
||||||
DBG("=== perf test ===");
|
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->init() == 0);
|
||||||
CHK(g_ndb->waitUntilReady() == 0);
|
CHK(g_ndb->waitUntilReady() == 0);
|
||||||
g_dic = g_ndb->getDictionary();
|
g_dic = g_ndb->getDictionary();
|
||||||
@ -1859,10 +1861,13 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
|
|||||||
strcat(b, "r");
|
strcat(b, "r");
|
||||||
g_opt.m_skip = strdup(b);
|
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;
|
ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl;
|
||||||
return NDBT_ProgramExit(NDBT_FAILED);
|
return NDBT_ProgramExit(NDBT_FAILED);
|
||||||
}
|
}
|
||||||
|
delete g_ncc;
|
||||||
|
g_ncc = 0;
|
||||||
return NDBT_ProgramExit(NDBT_OK);
|
return NDBT_ProgramExit(NDBT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ struct Opt {
|
|||||||
unsigned m_subloop;
|
unsigned m_subloop;
|
||||||
const char* m_table;
|
const char* m_table;
|
||||||
unsigned m_threads;
|
unsigned m_threads;
|
||||||
unsigned m_v;
|
int m_v;
|
||||||
Opt() :
|
Opt() :
|
||||||
m_batch(32),
|
m_batch(32),
|
||||||
m_bound("01234"),
|
m_bound("01234"),
|
||||||
@ -672,6 +672,8 @@ tabcount = sizeof(tablist) / sizeof(tablist[0]);
|
|||||||
|
|
||||||
// connections
|
// connections
|
||||||
|
|
||||||
|
static Ndb_cluster_connection* g_ncc = 0;
|
||||||
|
|
||||||
struct Con {
|
struct Con {
|
||||||
Ndb* m_ndb;
|
Ndb* m_ndb;
|
||||||
NdbDictionary::Dictionary* m_dic;
|
NdbDictionary::Dictionary* m_dic;
|
||||||
@ -720,7 +722,7 @@ int
|
|||||||
Con::connect()
|
Con::connect()
|
||||||
{
|
{
|
||||||
assert(m_ndb == 0);
|
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->init() == 0, *this);
|
||||||
CHKCON(m_ndb->waitUntilReady(30) == 0, *this);
|
CHKCON(m_ndb->waitUntilReady(30) == 0, *this);
|
||||||
m_tx = 0, m_op = 0;
|
m_tx = 0, m_op = 0;
|
||||||
@ -3514,8 +3516,11 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
Par par(g_opt);
|
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;
|
goto failed;
|
||||||
|
delete g_ncc;
|
||||||
|
g_ncc = 0;
|
||||||
}
|
}
|
||||||
// always exit with NDBT code
|
// always exit with NDBT code
|
||||||
ok:
|
ok:
|
||||||
|
@ -275,6 +275,7 @@ parse_args(int argc, const char** argv){
|
|||||||
int tmp = Logger::LL_WARNING - g_verbosity;
|
int tmp = Logger::LL_WARNING - g_verbosity;
|
||||||
tmp = (tmp < Logger::LL_DEBUG ? Logger::LL_DEBUG : tmp);
|
tmp = (tmp < Logger::LL_DEBUG ? Logger::LL_DEBUG : tmp);
|
||||||
g_logger.disable(Logger::LL_ALL);
|
g_logger.disable(Logger::LL_ALL);
|
||||||
|
g_logger.enable(Logger::LL_ON);
|
||||||
g_logger.enable((Logger::LoggerLevel)tmp, Logger::LL_ALERT);
|
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_server_read = NULL;
|
||||||
HANDLE event_client_wrote = NULL;
|
HANDLE event_client_wrote = NULL;
|
||||||
HANDLE event_client_read = NULL;
|
HANDLE event_client_read = NULL;
|
||||||
|
HANDLE event_conn_closed = NULL;
|
||||||
HANDLE handle_file_map = NULL;
|
HANDLE handle_file_map = NULL;
|
||||||
ulong connect_number;
|
ulong connect_number;
|
||||||
char connect_number_char[22], *p;
|
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;
|
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
|
||||||
goto err2;
|
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
|
Set event that server should send data
|
||||||
*/
|
*/
|
||||||
@ -514,9 +522,9 @@ err2:
|
|||||||
if (error_allow == 0)
|
if (error_allow == 0)
|
||||||
{
|
{
|
||||||
net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
|
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_server_read,event_client_wrote,
|
||||||
event_client_read);
|
event_client_read,event_conn_closed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -529,6 +537,8 @@ err2:
|
|||||||
CloseHandle(event_client_read);
|
CloseHandle(event_client_read);
|
||||||
if (event_client_wrote)
|
if (event_client_wrote)
|
||||||
CloseHandle(event_client_wrote);
|
CloseHandle(event_client_wrote);
|
||||||
|
if (event_conn_closed)
|
||||||
|
CloseHandle(event_conn_closed);
|
||||||
if (handle_map)
|
if (handle_map)
|
||||||
UnmapViewOfFile(handle_map);
|
UnmapViewOfFile(handle_map);
|
||||||
if (handle_file_map)
|
if (handle_file_map)
|
||||||
|
@ -380,15 +380,15 @@ convert_error_code_to_mysql(
|
|||||||
|
|
||||||
} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
|
} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
|
||||||
|
|
||||||
/* Since we rolled back the whole transaction, we must
|
/* Since we rolled back the whole transaction, we must
|
||||||
tell it also to MySQL so that MySQL knows to empty the
|
tell it also to MySQL so that MySQL knows to empty the
|
||||||
cached binlog for this transaction */
|
cached binlog for this transaction */
|
||||||
|
|
||||||
if (thd) {
|
if (thd) {
|
||||||
ha_rollback(thd);
|
ha_rollback(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(HA_ERR_LOCK_WAIT_TIMEOUT);
|
return(HA_ERR_LOCK_WAIT_TIMEOUT);
|
||||||
|
|
||||||
} else if (error == (int) DB_NO_REFERENCED_ROW) {
|
} 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);
|
err = row_import_tablespace_for_mysql(dict_table->name, trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
err = convert_error_code_to_mysql(err, NULL);
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
@ -5215,19 +5213,6 @@ ha_innobase::external_lock(
|
|||||||
|
|
||||||
update_thd(thd);
|
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;
|
trx = prebuilt->trx;
|
||||||
|
|
||||||
prebuilt->sql_stat_start = TRUE;
|
prebuilt->sql_stat_start = TRUE;
|
||||||
@ -5276,9 +5261,18 @@ ha_innobase::external_lock(
|
|||||||
prebuilt->select_lock_type = LOCK_S;
|
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 (prebuilt->select_lock_type != LOCK_NONE) {
|
||||||
|
|
||||||
if (thd->in_lock_tables &&
|
if (thd->in_lock_tables &&
|
||||||
thd->variables.innodb_table_locks) {
|
thd->variables.innodb_table_locks &&
|
||||||
|
(thd->options & OPTION_NOT_AUTOCOMMIT)) {
|
||||||
|
|
||||||
ulint error;
|
ulint error;
|
||||||
error = row_lock_table_for_mysql(prebuilt,
|
error = row_lock_table_for_mysql(prebuilt,
|
||||||
NULL, LOCK_TABLE_EXP);
|
NULL, LOCK_TABLE_EXP);
|
||||||
|
@ -661,12 +661,13 @@ longlong Item_in_optimizer::val_int()
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
cache->store(args[0]);
|
cache->store(args[0]);
|
||||||
|
longlong tmp= args[1]->val_int_result();
|
||||||
if (cache->null_value)
|
if (cache->null_value)
|
||||||
{
|
{
|
||||||
null_value= 1;
|
if (tmp)
|
||||||
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
longlong tmp= args[1]->val_int_result();
|
|
||||||
null_value= args[1]->null_value;
|
null_value= args[1]->null_value;
|
||||||
return tmp;
|
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,
|
bool Item_func_rand::fix_fields(THD *thd, struct st_table_list *tables,
|
||||||
Item **ref)
|
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;
|
used_tables_cache|= RAND_TABLE_BIT;
|
||||||
if (arg_count)
|
if (arg_count)
|
||||||
{ // Only use argument once in query
|
{ // Only use argument once in query
|
||||||
|
@ -1302,9 +1302,18 @@ String *Item_func_trim::val_str(String *str)
|
|||||||
return 0; /* purecov: inspected */
|
return 0; /* purecov: inspected */
|
||||||
char buff[MAX_FIELD_WIDTH];
|
char buff[MAX_FIELD_WIDTH];
|
||||||
String tmp(buff,sizeof(buff),res->charset());
|
String tmp(buff,sizeof(buff),res->charset());
|
||||||
String *remove_str= (arg_count==2) ? args[1]->val_str(&tmp) : &remove;
|
|
||||||
uint remove_length;
|
uint remove_length;
|
||||||
LINT_INIT(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 ||
|
if (!remove_str || (remove_length=remove_str->length()) == 0 ||
|
||||||
remove_length > res->length())
|
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
|
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;
|
goto null;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
As 'arg' and 'str' may be the same string, we must replace characters
|
As 'arg' and 'str' may be the same string, we must replace characters
|
||||||
from the end to the beginning
|
from the end to the beginning
|
||||||
*/
|
*/
|
||||||
to= (char*) str->ptr() + new_length - 1;
|
to= (char*) arg->ptr() + new_length - 1;
|
||||||
*to--= '\'';
|
*to--= '\'';
|
||||||
for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; 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= '\'';
|
*to= '\'';
|
||||||
str->length(new_length);
|
arg->length(new_length);
|
||||||
str->set_charset(collation.collation);
|
str->set_charset(collation.collation);
|
||||||
null_value= 0;
|
null_value= 0;
|
||||||
return str;
|
return arg;
|
||||||
|
|
||||||
null:
|
null:
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
|
@ -830,6 +830,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||||||
ref_pointer_array,
|
ref_pointer_array,
|
||||||
(char *)"<ref>",
|
(char *)"<ref>",
|
||||||
this->full_name()));
|
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()
|
AND and comparison functions can't be changed during fix_fields()
|
||||||
we can assign select_lex->having here, and pass 0 as last
|
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;
|
goto err;
|
||||||
item= new Item_cond_or(item,
|
item= new Item_cond_or(item,
|
||||||
new Item_func_isnull(orig_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;
|
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
|
we can assign select_lex->having here, and pass 0 as last
|
||||||
argument (reference) to fix_fields()
|
argument (reference) to fix_fields()
|
||||||
*/
|
*/
|
||||||
select_lex->having=
|
item= func->create(expr,
|
||||||
join->having=
|
|
||||||
func->create(expr,
|
|
||||||
new Item_null_helper(this, item,
|
new Item_null_helper(this, item,
|
||||||
(char *)"<no matter>",
|
(char *)"<no matter>",
|
||||||
(char *)"<result>"));
|
(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;
|
select_lex->having_fix_field= 1;
|
||||||
tmp= join->having->fix_fields(thd, join->tables_list, 0);
|
tmp= join->having->fix_fields(thd, join->tables_list, 0);
|
||||||
select_lex->having_fix_field= 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.
|
conversion specifiers that can be used in such sub-patterns is limited.
|
||||||
Also most of checks are skipped in this case.
|
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
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
1 error
|
1 error
|
||||||
@ -2821,25 +2824,31 @@ void Item_func_get_format::print(String *str)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
check_result_type(s, l) returns DATE/TIME type
|
Get type of datetime value (DATE/TIME/...) which will be produced
|
||||||
according to format string
|
according to format string.
|
||||||
|
|
||||||
s: DATE/TIME format string
|
SYNOPSIS
|
||||||
l: length of s
|
get_date_time_result_type()
|
||||||
Result: date_time_format_types value:
|
format - format string
|
||||||
DATE_TIME_MICROSECOND, DATE_TIME,
|
length - length of format string
|
||||||
TIME_MICROSECOND, TIME_ONLY
|
|
||||||
|
|
||||||
We don't process day format's characters('D', 'd', 'e')
|
NOTE
|
||||||
because day may be a member of all date/time types.
|
We don't process day format's characters('D', 'd', 'e') because day
|
||||||
If only day format's character and no time part present
|
may be a member of all date/time types.
|
||||||
the result type is MYSQL_TYPE_DATE
|
|
||||||
|
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 *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;
|
bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
|
||||||
|
|
||||||
const char *val= format;
|
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)
|
if (*val == '%' && val+1 != end)
|
||||||
{
|
{
|
||||||
val++;
|
val++;
|
||||||
if ((frac_second_used= (*val == 'f')) ||
|
if (*val == 'f')
|
||||||
(!time_part_used && strchr(time_part_frms, *val)))
|
frac_second_used= time_part_used= 1;
|
||||||
|
else if (!time_part_used && strchr(time_part_frms, *val))
|
||||||
time_part_used= 1;
|
time_part_used= 1;
|
||||||
else if (!date_part_used && strchr(date_part_frms, *val))
|
else if (!date_part_used && strchr(date_part_frms, *val))
|
||||||
date_part_used= 1;
|
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;
|
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 (time_part_used)
|
||||||
{
|
{
|
||||||
if (date_part_used)
|
if (date_part_used)
|
||||||
return DATE_TIME;
|
return DATE_TIME;
|
||||||
if (frac_second_used)
|
|
||||||
return TIME_MICROSECOND;
|
|
||||||
return TIME_ONLY;
|
return TIME_ONLY;
|
||||||
}
|
}
|
||||||
return DATE_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()))
|
if ((const_item= args[1]->const_item()))
|
||||||
{
|
{
|
||||||
format= args[1]->val_str(&format_str);
|
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) {
|
switch (cached_format_type) {
|
||||||
case DATE_ONLY:
|
case DATE_ONLY:
|
||||||
cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
|
cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
|
||||||
|
@ -2046,6 +2046,7 @@ bool flush_error_log()
|
|||||||
char err_renamed[FN_REFLEN], *end;
|
char err_renamed[FN_REFLEN], *end;
|
||||||
end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
|
end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
|
||||||
strmov(end, "-old");
|
strmov(end, "-old");
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_error_log));
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
char err_temp[FN_REFLEN+4];
|
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)
|
if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
|
||||||
{
|
{
|
||||||
while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE, 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));
|
my_close(fd, MYF(0));
|
||||||
}
|
}
|
||||||
(void) my_delete(err_temp, MYF(0));
|
(void) my_delete(err_temp, MYF(0));
|
||||||
@ -2080,6 +2081,7 @@ bool flush_error_log()
|
|||||||
else
|
else
|
||||||
result= 1;
|
result= 1;
|
||||||
#endif
|
#endif
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_error_log));
|
||||||
}
|
}
|
||||||
return result;
|
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);
|
char **err_pos, uint *err_len, bool *set_warning);
|
||||||
uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
|
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);
|
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,
|
uint check_word(TYPELIB *lib, const char *val, const char *end,
|
||||||
const char **end_of_word);
|
const char **end_of_word);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NDBCLUSTER_DB
|
#ifdef HAVE_NDBCLUSTER_DB
|
||||||
#define OPT_NDBCLUSTER_DEFAULT 0
|
#define OPT_NDBCLUSTER_DEFAULT 0
|
||||||
#ifdef NDB_SHM_TRANSPORTER
|
#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
|
||||||
#define OPT_NDB_SHM_DEFAULT 1
|
#define OPT_NDB_SHM_DEFAULT 1
|
||||||
#else
|
#else
|
||||||
#define OPT_NDB_SHM_DEFAULT 0
|
#define OPT_NDB_SHM_DEFAULT 0
|
||||||
@ -141,15 +141,6 @@ extern "C" { // Because of SCO 3.2V4.2
|
|||||||
int allow_severity = LOG_INFO;
|
int allow_severity = LOG_INFO;
|
||||||
int deny_severity = LOG_WARNING;
|
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 */
|
#endif /* HAVE_LIBWRAP */
|
||||||
|
|
||||||
#ifdef HAVE_SYS_MMAN_H
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
@ -3689,8 +3680,8 @@ extern "C" pthread_handler_decl(handle_connections_sockets,
|
|||||||
struct request_info req;
|
struct request_info req;
|
||||||
signal(SIGCHLD, SIG_DFL);
|
signal(SIGCHLD, SIG_DFL);
|
||||||
request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
|
request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
|
||||||
my_fromhost(&req);
|
fromhost(&req);
|
||||||
if (!my_hosts_access(&req))
|
if (!hosts_access(&req))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This may be stupid but refuse() includes an exit(0)
|
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 ...
|
clean_exit() - same stupid thing ...
|
||||||
*/
|
*/
|
||||||
syslog(deny_severity, "refused connect from %s",
|
syslog(deny_severity, "refused connect from %s",
|
||||||
my_eval_client(&req));
|
eval_client(&req));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
C++ sucks (the gibberish in front just translates the supplied
|
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_client_read= 0; // for transfer data server <-> client
|
||||||
HANDLE event_server_wrote= 0;
|
HANDLE event_server_wrote= 0;
|
||||||
HANDLE event_server_read= 0;
|
HANDLE event_server_read= 0;
|
||||||
|
HANDLE event_conn_closed= 0;
|
||||||
THD *thd= 0;
|
THD *thd= 0;
|
||||||
|
|
||||||
p= int10_to_str(connect_number, connect_number_char, 10);
|
p= int10_to_str(connect_number, connect_number_char, 10);
|
||||||
@ -3969,29 +3961,35 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
|
|||||||
goto errorconn;
|
goto errorconn;
|
||||||
}
|
}
|
||||||
strmov(suffix_pos, "CLIENT_WROTE");
|
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";
|
errmsg= "Could not create client write event";
|
||||||
goto errorconn;
|
goto errorconn;
|
||||||
}
|
}
|
||||||
strmov(suffix_pos, "CLIENT_READ");
|
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";
|
errmsg= "Could not create client read event";
|
||||||
goto errorconn;
|
goto errorconn;
|
||||||
}
|
}
|
||||||
strmov(suffix_pos, "SERVER_READ");
|
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";
|
errmsg= "Could not create server read event";
|
||||||
goto errorconn;
|
goto errorconn;
|
||||||
}
|
}
|
||||||
strmov(suffix_pos, "SERVER_WROTE");
|
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";
|
errmsg= "Could not create server write event";
|
||||||
goto errorconn;
|
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)
|
if (abort_loop)
|
||||||
goto errorconn;
|
goto errorconn;
|
||||||
if (!(thd= new THD))
|
if (!(thd= new THD))
|
||||||
@ -4010,13 +4008,14 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
|
|||||||
goto errorconn;
|
goto errorconn;
|
||||||
}
|
}
|
||||||
if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net,
|
if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net,
|
||||||
handle_client_file_map,
|
handle_client_file_map,
|
||||||
handle_client_map,
|
handle_client_map,
|
||||||
event_client_wrote,
|
event_client_wrote,
|
||||||
event_client_read,
|
event_client_read,
|
||||||
event_server_wrote,
|
event_server_wrote,
|
||||||
event_server_read)) ||
|
event_server_read,
|
||||||
my_net_init(&thd->net, thd->net.vio))
|
event_conn_closed)) ||
|
||||||
|
my_net_init(&thd->net, thd->net.vio))
|
||||||
{
|
{
|
||||||
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
||||||
errmsg= 0;
|
errmsg= 0;
|
||||||
@ -4036,12 +4035,20 @@ errorconn:
|
|||||||
NullS);
|
NullS);
|
||||||
sql_perror(buff);
|
sql_perror(buff);
|
||||||
}
|
}
|
||||||
if (handle_client_file_map) CloseHandle(handle_client_file_map);
|
if (handle_client_file_map)
|
||||||
if (handle_client_map) UnmapViewOfFile(handle_client_map);
|
CloseHandle(handle_client_file_map);
|
||||||
if (event_server_wrote) CloseHandle(event_server_wrote);
|
if (handle_client_map)
|
||||||
if (event_server_read) CloseHandle(event_server_read);
|
UnmapViewOfFile(handle_client_map);
|
||||||
if (event_client_wrote) CloseHandle(event_client_wrote);
|
if (event_server_wrote)
|
||||||
if (event_client_read) CloseHandle(event_client_read);
|
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;
|
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)
|
if (var->value->result_type() == STRING_RESULT)
|
||||||
{
|
{
|
||||||
|
enum db_type db_type;
|
||||||
if (!(res=var->value->val_str(&str)) ||
|
if (!(res=var->value->val_str(&str)) ||
|
||||||
!(var->save_result.ulong_value=
|
!(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";
|
value= res ? res->c_ptr() : "NULL";
|
||||||
goto err;
|
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;
|
Field **tmp_field;
|
||||||
ulong priv;
|
ulong priv;
|
||||||
|
uint next_field;
|
||||||
for (tmp_field= table->field+3, priv = SELECT_ACL;
|
for (tmp_field= table->field+3, priv = SELECT_ACL;
|
||||||
*tmp_field && (*tmp_field)->real_type() == FIELD_TYPE_ENUM &&
|
*tmp_field && (*tmp_field)->real_type() == FIELD_TYPE_ENUM &&
|
||||||
((Field_enum*) (*tmp_field))->typelib->count == 2 ;
|
((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
|
if (priv & rights) // set requested privileges
|
||||||
(*tmp_field)->store(&what, 1, &my_charset_latin1);
|
(*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));
|
DBUG_PRINT("info",("table->fields: %d",table->fields));
|
||||||
if (table->fields >= 31) /* From 4.0.0 we have more fields */
|
if (table->fields >= 31) /* From 4.0.0 we have more fields */
|
||||||
{
|
{
|
||||||
/* We write down SSL related ACL stuff */
|
/* We write down SSL related ACL stuff */
|
||||||
switch (lex->ssl_type) {
|
switch (lex->ssl_type) {
|
||||||
case SSL_TYPE_ANY:
|
case SSL_TYPE_ANY:
|
||||||
table->field[24]->store("ANY",3, &my_charset_latin1);
|
table->field[next_field]->store("ANY", 3, &my_charset_latin1);
|
||||||
table->field[25]->store("", 0, &my_charset_latin1);
|
table->field[next_field+1]->store("", 0, &my_charset_latin1);
|
||||||
table->field[26]->store("", 0, &my_charset_latin1);
|
table->field[next_field+2]->store("", 0, &my_charset_latin1);
|
||||||
table->field[27]->store("", 0, &my_charset_latin1);
|
table->field[next_field+3]->store("", 0, &my_charset_latin1);
|
||||||
break;
|
break;
|
||||||
case SSL_TYPE_X509:
|
case SSL_TYPE_X509:
|
||||||
table->field[24]->store("X509",4, &my_charset_latin1);
|
table->field[next_field]->store("X509", 4, &my_charset_latin1);
|
||||||
table->field[25]->store("", 0, &my_charset_latin1);
|
table->field[next_field+1]->store("", 0, &my_charset_latin1);
|
||||||
table->field[26]->store("", 0, &my_charset_latin1);
|
table->field[next_field+2]->store("", 0, &my_charset_latin1);
|
||||||
table->field[27]->store("", 0, &my_charset_latin1);
|
table->field[next_field+3]->store("", 0, &my_charset_latin1);
|
||||||
break;
|
break;
|
||||||
case SSL_TYPE_SPECIFIED:
|
case SSL_TYPE_SPECIFIED:
|
||||||
table->field[24]->store("SPECIFIED",9, &my_charset_latin1);
|
table->field[next_field]->store("SPECIFIED", 9, &my_charset_latin1);
|
||||||
table->field[25]->store("", 0, &my_charset_latin1);
|
table->field[next_field+1]->store("", 0, &my_charset_latin1);
|
||||||
table->field[26]->store("", 0, &my_charset_latin1);
|
table->field[next_field+2]->store("", 0, &my_charset_latin1);
|
||||||
table->field[27]->store("", 0, &my_charset_latin1);
|
table->field[next_field+3]->store("", 0, &my_charset_latin1);
|
||||||
if (lex->ssl_cipher)
|
if (lex->ssl_cipher)
|
||||||
table->field[25]->store(lex->ssl_cipher,
|
table->field[next_field+1]->store(lex->ssl_cipher,
|
||||||
strlen(lex->ssl_cipher), system_charset_info);
|
strlen(lex->ssl_cipher), system_charset_info);
|
||||||
if (lex->x509_issuer)
|
if (lex->x509_issuer)
|
||||||
table->field[26]->store(lex->x509_issuer,
|
table->field[next_field+2]->store(lex->x509_issuer,
|
||||||
strlen(lex->x509_issuer), system_charset_info);
|
strlen(lex->x509_issuer), system_charset_info);
|
||||||
if (lex->x509_subject)
|
if (lex->x509_subject)
|
||||||
table->field[27]->store(lex->x509_subject,
|
table->field[next_field+3]->store(lex->x509_subject,
|
||||||
strlen(lex->x509_subject), system_charset_info);
|
strlen(lex->x509_subject), system_charset_info);
|
||||||
break;
|
break;
|
||||||
case SSL_TYPE_NOT_SPECIFIED:
|
case SSL_TYPE_NOT_SPECIFIED:
|
||||||
break;
|
break;
|
||||||
case SSL_TYPE_NONE:
|
case SSL_TYPE_NONE:
|
||||||
table->field[24]->store("", 0, &my_charset_latin1);
|
table->field[next_field]->store("", 0, &my_charset_latin1);
|
||||||
table->field[25]->store("", 0, &my_charset_latin1);
|
table->field[next_field+1]->store("", 0, &my_charset_latin1);
|
||||||
table->field[26]->store("", 0, &my_charset_latin1);
|
table->field[next_field+2]->store("", 0, &my_charset_latin1);
|
||||||
table->field[27]->store("", 0, &my_charset_latin1);
|
table->field[next_field+3]->store("", 0, &my_charset_latin1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
next_field+=4;
|
||||||
|
|
||||||
USER_RESOURCES mqh= lex->mqh;
|
USER_RESOURCES mqh= lex->mqh;
|
||||||
if (mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
|
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)
|
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)
|
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 &&
|
if (table->fields >= 36 &&
|
||||||
(mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
|
(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;
|
mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
|
||||||
}
|
}
|
||||||
if (old_row_exists)
|
if (old_row_exists)
|
||||||
@ -2587,41 +2589,59 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (columns.elements && !revoke_grant)
|
if (!revoke_grant)
|
||||||
{
|
{
|
||||||
class LEX_COLUMN *column;
|
if (columns.elements)
|
||||||
List_iterator <LEX_COLUMN> column_iter(columns);
|
{
|
||||||
int res;
|
class LEX_COLUMN *column;
|
||||||
|
List_iterator <LEX_COLUMN> column_iter(columns);
|
||||||
|
int res;
|
||||||
|
|
||||||
if (open_and_lock_tables(thd, table_list))
|
if (open_and_lock_tables(thd, table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
while ((column = column_iter++))
|
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))
|
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
uint unused_field_idx= NO_CACHED_FIELD_INDEX;
|
||||||
column->column.c_ptr(), table_list->alias);
|
Field *f=find_field_in_table(thd, table_list, column->column.ptr(),
|
||||||
DBUG_RETURN(TRUE);
|
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
|
||||||
}
|
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
|
if (!(rights & CREATE_ACL))
|
||||||
DBUG_RETURN(TRUE);
|
{
|
||||||
|
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);
|
rw_unlock(&LOCK_grant);
|
||||||
if (!no_errors) // Not a silent skip of table
|
if (!no_errors) // Not a silent skip of table
|
||||||
{
|
{
|
||||||
const char *command="";
|
char command[128];
|
||||||
if (want_access & SELECT_ACL)
|
get_privilege_desc(command, sizeof(command), want_access);
|
||||||
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";
|
|
||||||
else if (want_access & CREATE_VIEW_ACL)
|
else if (want_access & CREATE_VIEW_ACL)
|
||||||
command= "create view";
|
command= "create view";
|
||||||
else if (want_access & SHOW_VIEW_ACL)
|
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:
|
err:
|
||||||
rw_unlock(&LOCK_grant);
|
rw_unlock(&LOCK_grant);
|
||||||
err2:
|
err2:
|
||||||
const char *command= "";
|
char command[128];
|
||||||
if (want_access & SELECT_ACL)
|
get_privilege_desc(command, sizeof(command), want_access);
|
||||||
command= "select";
|
|
||||||
else if (want_access & INSERT_ACL)
|
|
||||||
command= "insert";
|
|
||||||
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
|
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
|
||||||
command,
|
command,
|
||||||
thd->priv_user,
|
thd->priv_user,
|
||||||
|
@ -702,9 +702,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
|
|||||||
if (!table)
|
if (!table)
|
||||||
table= table_list->table;
|
table= table_list->table;
|
||||||
|
|
||||||
if ((thd->lex->sql_command == SQLCOM_INSERT ||
|
if (!select_insert && unique_table(table_list, table_list->next_global))
|
||||||
thd->lex->sql_command == SQLCOM_REPLACE) &&
|
|
||||||
unique_table(table_list, table_list->next_global))
|
|
||||||
{
|
{
|
||||||
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
|
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
|
||||||
DBUG_RETURN(TRUE);
|
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