Merge from Tim's 5.0.76-release tree to make 5.0.77 .
This commit is contained in:
commit
f68ccd024a
@ -1,4 +1,4 @@
|
|||||||
[MYSQL]
|
[MYSQL]
|
||||||
post_commit_to = "commits@lists.mysql.com"
|
post_commit_to = "commits@lists.mysql.com"
|
||||||
post_push_to = "commits@lists.mysql.com"
|
post_push_to = "commits@lists.mysql.com"
|
||||||
tree_name = "mysql-5.0"
|
tree_name = "mysql-5.0-bugteam"
|
||||||
|
@ -1998,7 +1998,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
|
|||||||
{
|
{
|
||||||
if (!preserve_comments)
|
if (!preserve_comments)
|
||||||
{
|
{
|
||||||
// Skip spaces at the beggining of a statement
|
// Skip spaces at the beginning of a statement
|
||||||
if (my_isspace(charset_info,inchar) && (out == line) &&
|
if (my_isspace(charset_info,inchar) && (out == line) &&
|
||||||
buffer.is_empty())
|
buffer.is_empty())
|
||||||
continue;
|
continue;
|
||||||
@ -2081,37 +2081,6 @@ static bool add_line(String &buffer,char *line,char *in_string,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!*ml_comment && !*in_string &&
|
|
||||||
(end_of_line - pos) >= 10 &&
|
|
||||||
!my_strnncoll(charset_info, (uchar*) pos, 10,
|
|
||||||
(const uchar*) "delimiter ", 10))
|
|
||||||
{
|
|
||||||
// Flush previously accepted characters
|
|
||||||
if (out != line)
|
|
||||||
{
|
|
||||||
buffer.append(line, (uint32) (out - line));
|
|
||||||
out= line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush possible comments in the buffer
|
|
||||||
if (!buffer.is_empty())
|
|
||||||
{
|
|
||||||
if (com_go(&buffer, 0) > 0) // < 0 is not fatal
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
buffer.length(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Delimiter wants the get rest of the given line as argument to
|
|
||||||
allow one to change ';' to ';;' and back
|
|
||||||
*/
|
|
||||||
buffer.append(pos);
|
|
||||||
if (com_delimiter(&buffer, pos) > 0)
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
|
|
||||||
buffer.length(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
|
else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
|
||||||
{
|
{
|
||||||
// Found a statement. Continue parsing after the delimiter
|
// Found a statement. Continue parsing after the delimiter
|
||||||
@ -2174,8 +2143,24 @@ static bool add_line(String &buffer,char *line,char *in_string,
|
|||||||
|
|
||||||
// comment to end of line
|
// comment to end of line
|
||||||
if (preserve_comments)
|
if (preserve_comments)
|
||||||
|
{
|
||||||
|
bool started_with_nothing= !buffer.length();
|
||||||
|
|
||||||
buffer.append(pos);
|
buffer.append(pos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
A single-line comment by itself gets sent immediately so that
|
||||||
|
client commands (delimiter, status, etc) will be interpreted on
|
||||||
|
the next line.
|
||||||
|
*/
|
||||||
|
if (started_with_nothing)
|
||||||
|
{
|
||||||
|
if (com_go(&buffer, 0) > 0) // < 0 is not fatal
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
buffer.length(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!*in_string && inchar == '/' && *(pos+1) == '*' &&
|
else if (!*in_string && inchar == '/' && *(pos+1) == '*' &&
|
||||||
|
@ -248,6 +248,15 @@ inline double ulonglong2double(ulonglong value)
|
|||||||
#define my_off_t2double(A) ulonglong2double(A)
|
#define my_off_t2double(A) ulonglong2double(A)
|
||||||
#endif /* _WIN64 */
|
#endif /* _WIN64 */
|
||||||
|
|
||||||
|
inline ulonglong double2ulonglong(double d)
|
||||||
|
{
|
||||||
|
double t= d - (double) 0x8000000000000000ULL;
|
||||||
|
|
||||||
|
if (t >= 0)
|
||||||
|
return ((ulonglong) t) + 0x8000000000000000ULL;
|
||||||
|
return (ulonglong) d;
|
||||||
|
}
|
||||||
|
|
||||||
#if SIZEOF_OFF_T > 4
|
#if SIZEOF_OFF_T > 4
|
||||||
#define lseek(A,B,C) _lseeki64((A),(longlong) (B),(C))
|
#define lseek(A,B,C) _lseeki64((A),(longlong) (B),(C))
|
||||||
#define tell(A) _telli64(A)
|
#define tell(A) _telli64(A)
|
||||||
|
@ -445,6 +445,7 @@ my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, uint len);
|
|||||||
uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len);
|
uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len);
|
||||||
my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
|
my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
|
||||||
my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs);
|
my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs);
|
||||||
|
uint my_charset_repertoire(CHARSET_INFO *cs);
|
||||||
|
|
||||||
|
|
||||||
#define _MY_U 01 /* Upper case */
|
#define _MY_U 01 /* Upper case */
|
||||||
|
@ -713,6 +713,9 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
|||||||
#define ulonglong2double(A) ((double) (ulonglong) (A))
|
#define ulonglong2double(A) ((double) (ulonglong) (A))
|
||||||
#define my_off_t2double(A) ((double) (my_off_t) (A))
|
#define my_off_t2double(A) ((double) (my_off_t) (A))
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef double2ulonglong
|
||||||
|
#define double2ulonglong(A) ((ulonglong) (double) (A))
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
|
@ -52,7 +52,7 @@ can be released by page reorganize, then it is reorganized */
|
|||||||
|
|
||||||
#define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
|
#define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
|
||||||
|
|
||||||
/* When estimating number of different kay values in an index sample
|
/* When estimating number of different key values in an index, sample
|
||||||
this many index pages */
|
this many index pages */
|
||||||
#define BTR_KEY_VAL_ESTIMATE_N_PAGES 8
|
#define BTR_KEY_VAL_ESTIMATE_N_PAGES 8
|
||||||
|
|
||||||
|
@ -162,6 +162,8 @@ btr_search_info_create(
|
|||||||
|
|
||||||
info->last_search = NULL;
|
info->last_search = NULL;
|
||||||
info->n_direction = 0;
|
info->n_direction = 0;
|
||||||
|
|
||||||
|
info->ref_count = 0;
|
||||||
info->root_guess = NULL;
|
info->root_guess = NULL;
|
||||||
|
|
||||||
info->hash_analysis = 0;
|
info->hash_analysis = 0;
|
||||||
@ -183,6 +185,31 @@ btr_search_info_create(
|
|||||||
return(info);
|
return(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
Returns the value of ref_count. The value is protected by
|
||||||
|
btr_search_latch. */
|
||||||
|
ulint
|
||||||
|
btr_search_info_get_ref_count(
|
||||||
|
/*==========================*/
|
||||||
|
/* out: ref_count value. */
|
||||||
|
btr_search_t* info) /* in: search info. */
|
||||||
|
{
|
||||||
|
ulint ret;
|
||||||
|
|
||||||
|
ut_ad(info);
|
||||||
|
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
|
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
|
||||||
|
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
|
rw_lock_s_lock(&btr_search_latch);
|
||||||
|
ret = info->ref_count;
|
||||||
|
rw_lock_s_unlock(&btr_search_latch);
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Updates the search info of an index about hash successes. NOTE that info
|
Updates the search info of an index about hash successes. NOTE that info
|
||||||
is NOT protected by any semaphore, to save CPU time! Do not assume its fields
|
is NOT protected by any semaphore, to save CPU time! Do not assume its fields
|
||||||
@ -1019,8 +1046,12 @@ next_rec:
|
|||||||
ha_remove_all_nodes_to_page(table, folds[i], page);
|
ha_remove_all_nodes_to_page(table, folds[i], page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_a(index->search_info->ref_count > 0);
|
||||||
|
index->search_info->ref_count--;
|
||||||
|
|
||||||
block->is_hashed = FALSE;
|
block->is_hashed = FALSE;
|
||||||
block->index = NULL;
|
block->index = NULL;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (UNIV_UNLIKELY(block->n_pointers)) {
|
if (UNIV_UNLIKELY(block->n_pointers)) {
|
||||||
/* Corruption */
|
/* Corruption */
|
||||||
@ -1241,6 +1272,15 @@ btr_search_build_page_hash_index(
|
|||||||
goto exit_func;
|
goto exit_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This counter is decremented every time we drop page
|
||||||
|
hash index entries and is incremented here. Since we can
|
||||||
|
rebuild hash index for a page that is already hashed, we
|
||||||
|
have to take care not to increment the counter in that
|
||||||
|
case. */
|
||||||
|
if (!block->is_hashed) {
|
||||||
|
index->search_info->ref_count++;
|
||||||
|
}
|
||||||
|
|
||||||
block->is_hashed = TRUE;
|
block->is_hashed = TRUE;
|
||||||
block->n_hash_helps = 0;
|
block->n_hash_helps = 0;
|
||||||
|
|
||||||
|
@ -1556,6 +1556,8 @@ dict_index_remove_from_cache(
|
|||||||
dict_field_t* field;
|
dict_field_t* field;
|
||||||
ulint size;
|
ulint size;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
ulint retries = 0;
|
||||||
|
btr_search_t* info;
|
||||||
|
|
||||||
ut_ad(table && index);
|
ut_ad(table && index);
|
||||||
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||||
@ -1564,6 +1566,51 @@ dict_index_remove_from_cache(
|
|||||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
|
/* We always create search info whether or not adaptive
|
||||||
|
hash index is enabled or not. */
|
||||||
|
info = index->search_info;
|
||||||
|
ut_ad(info);
|
||||||
|
|
||||||
|
/* We are not allowed to free the in-memory index struct
|
||||||
|
dict_index_t until all entries in the adaptive hash index
|
||||||
|
that point to any of the page belonging to his b-tree index
|
||||||
|
are dropped. This is so because dropping of these entries
|
||||||
|
require access to dict_index_t struct. To avoid such scenario
|
||||||
|
We keep a count of number of such pages in the search_info and
|
||||||
|
only free the dict_index_t struct when this count drops to
|
||||||
|
zero. */
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ulint ref_count = btr_search_info_get_ref_count(info);
|
||||||
|
if (ref_count == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sleep for 10ms before trying again. */
|
||||||
|
os_thread_sleep(10000);
|
||||||
|
++retries;
|
||||||
|
|
||||||
|
if (retries % 500 == 0) {
|
||||||
|
/* No luck after 5 seconds of wait. */
|
||||||
|
fprintf(stderr, "InnoDB: Error: Waited for"
|
||||||
|
" %lu secs for hash index"
|
||||||
|
" ref_count (%lu) to drop"
|
||||||
|
" to 0.\n"
|
||||||
|
"index: \"%s\""
|
||||||
|
" table: \"%s\"\n",
|
||||||
|
retries/100,
|
||||||
|
ref_count,
|
||||||
|
index->name,
|
||||||
|
table->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To avoid a hang here we commit suicide if the
|
||||||
|
ref_count doesn't drop to zero in 600 seconds. */
|
||||||
|
if (retries >= 60000) {
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ut_ad(UT_LIST_GET_LEN((index->tree)->tree_indexes) == 1);
|
ut_ad(UT_LIST_GET_LEN((index->tree)->tree_indexes) == 1);
|
||||||
dict_tree_free(index->tree);
|
dict_tree_free(index->tree);
|
||||||
|
|
||||||
|
@ -40,6 +40,14 @@ btr_search_info_create(
|
|||||||
/*===================*/
|
/*===================*/
|
||||||
/* out, own: search info struct */
|
/* out, own: search info struct */
|
||||||
mem_heap_t* heap); /* in: heap where created */
|
mem_heap_t* heap); /* in: heap where created */
|
||||||
|
/*********************************************************************
|
||||||
|
Returns the value of ref_count. The value is protected by
|
||||||
|
btr_search_latch. */
|
||||||
|
ulint
|
||||||
|
btr_search_info_get_ref_count(
|
||||||
|
/*==========================*/
|
||||||
|
/* out: ref_count value. */
|
||||||
|
btr_search_t* info); /* in: search info. */
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Updates the search info. */
|
Updates the search info. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
@ -144,6 +152,13 @@ btr_search_validate(void);
|
|||||||
|
|
||||||
struct btr_search_struct{
|
struct btr_search_struct{
|
||||||
ulint magic_n; /* magic number */
|
ulint magic_n; /* magic number */
|
||||||
|
ulint ref_count; /* Number of blocks in this index tree
|
||||||
|
that have search index built
|
||||||
|
i.e. block->index points to this index.
|
||||||
|
Protected by btr_search_latch except
|
||||||
|
when during initialization in
|
||||||
|
btr_search_info_create(). */
|
||||||
|
|
||||||
/* The following 4 fields are currently not used: */
|
/* The following 4 fields are currently not used: */
|
||||||
rec_t* last_search; /* pointer to the lower limit record of the
|
rec_t* last_search; /* pointer to the lower limit record of the
|
||||||
previous search; NULL if not known */
|
previous search; NULL if not known */
|
||||||
@ -154,8 +169,10 @@ struct btr_search_struct{
|
|||||||
or BTR_SEA_SAME_PAGE */
|
or BTR_SEA_SAME_PAGE */
|
||||||
dulint modify_clock; /* value of modify clock at the time
|
dulint modify_clock; /* value of modify clock at the time
|
||||||
last_search was stored */
|
last_search was stored */
|
||||||
/*----------------------*/
|
|
||||||
/* The following 4 fields are not protected by any latch: */
|
/* The following fields are not protected by any latch.
|
||||||
|
Unfortunately, this means that they must be aligned to
|
||||||
|
the machine word, i.e., they cannot be turned into bit-fields. */
|
||||||
page_t* root_guess; /* the root page frame when it was last time
|
page_t* root_guess; /* the root page frame when it was last time
|
||||||
fetched, or NULL */
|
fetched, or NULL */
|
||||||
ulint hash_analysis; /* when this exceeds a certain value, the
|
ulint hash_analysis; /* when this exceeds a certain value, the
|
||||||
|
@ -139,11 +139,15 @@ ib_time_t
|
|||||||
ut_time(void);
|
ut_time(void);
|
||||||
/*=========*/
|
/*=========*/
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
Returns system time. */
|
Returns system time.
|
||||||
|
Upon successful completion, the value 0 is returned; otherwise the
|
||||||
|
value -1 is returned and the global variable errno is set to indicate the
|
||||||
|
error. */
|
||||||
|
|
||||||
void
|
int
|
||||||
ut_usectime(
|
ut_usectime(
|
||||||
/*========*/
|
/*========*/
|
||||||
|
/* out: 0 on success, -1 otherwise */
|
||||||
ulint* sec, /* out: seconds since the Epoch */
|
ulint* sec, /* out: seconds since the Epoch */
|
||||||
ulint* ms); /* out: microseconds since the Epoch+*sec */
|
ulint* ms); /* out: microseconds since the Epoch+*sec */
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
|
@ -1372,7 +1372,7 @@ srv_table_reserve_slot_for_mysql(void)
|
|||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
Puts a MySQL OS thread to wait for a lock to be released. If an error
|
Puts a MySQL OS thread to wait for a lock to be released. If an error
|
||||||
occurs during the wait trx->error_state associated with thr is
|
occurs during the wait, then trx->error_state associated with thr is
|
||||||
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
|
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
|
||||||
are possible errors. DB_DEADLOCK is returned if selective deadlock
|
are possible errors. DB_DEADLOCK is returned if selective deadlock
|
||||||
resolution chose this transaction as a victim. */
|
resolution chose this transaction as a victim. */
|
||||||
@ -1442,8 +1442,11 @@ srv_suspend_mysql_thread(
|
|||||||
srv_n_lock_wait_count++;
|
srv_n_lock_wait_count++;
|
||||||
srv_n_lock_wait_current_count++;
|
srv_n_lock_wait_current_count++;
|
||||||
|
|
||||||
ut_usectime(&sec, &ms);
|
if (ut_usectime(&sec, &ms) == -1) {
|
||||||
start_time = (ib_longlong)sec * 1000000 + ms;
|
start_time = -1;
|
||||||
|
} else {
|
||||||
|
start_time = (ib_longlong)sec * 1000000 + ms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Wake the lock timeout monitor thread, if it is suspended */
|
/* Wake the lock timeout monitor thread, if it is suspended */
|
||||||
|
|
||||||
@ -1497,14 +1500,20 @@ srv_suspend_mysql_thread(
|
|||||||
wait_time = ut_difftime(ut_time(), slot->suspend_time);
|
wait_time = ut_difftime(ut_time(), slot->suspend_time);
|
||||||
|
|
||||||
if (thr->lock_state == QUE_THR_LOCK_ROW) {
|
if (thr->lock_state == QUE_THR_LOCK_ROW) {
|
||||||
ut_usectime(&sec, &ms);
|
if (ut_usectime(&sec, &ms) == -1) {
|
||||||
finish_time = (ib_longlong)sec * 1000000 + ms;
|
finish_time = -1;
|
||||||
|
} else {
|
||||||
|
finish_time = (ib_longlong)sec * 1000000 + ms;
|
||||||
|
}
|
||||||
|
|
||||||
diff_time = (ulint) (finish_time - start_time);
|
diff_time = (ulint) (finish_time - start_time);
|
||||||
|
|
||||||
srv_n_lock_wait_current_count--;
|
srv_n_lock_wait_current_count--;
|
||||||
srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time;
|
srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time;
|
||||||
if (diff_time > srv_n_lock_max_wait_time) {
|
if (diff_time > srv_n_lock_max_wait_time &&
|
||||||
|
/* only update the variable if we successfully
|
||||||
|
retrieved the start and finish times. See Bug#36819. */
|
||||||
|
start_time != -1 && finish_time != -1) {
|
||||||
srv_n_lock_max_wait_time = diff_time;
|
srv_n_lock_max_wait_time = diff_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,11 +180,11 @@ srv_parse_data_file_paths_and_sizes(
|
|||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) {
|
if (0 == strncmp(str, ":autoextend", (sizeof ":autoextend") - 1)) {
|
||||||
|
|
||||||
str += (sizeof ":autoextend") - 1;
|
str += (sizeof ":autoextend") - 1;
|
||||||
|
|
||||||
if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) {
|
if (0 == strncmp(str, ":max:", (sizeof ":max:") - 1)) {
|
||||||
|
|
||||||
str += (sizeof ":max:") - 1;
|
str += (sizeof ":max:") - 1;
|
||||||
|
|
||||||
@ -288,13 +288,13 @@ srv_parse_data_file_paths_and_sizes(
|
|||||||
(*data_file_names)[i] = path;
|
(*data_file_names)[i] = path;
|
||||||
(*data_file_sizes)[i] = size;
|
(*data_file_sizes)[i] = size;
|
||||||
|
|
||||||
if (0 == memcmp(str, ":autoextend", (sizeof ":autoextend") - 1)) {
|
if (0 == strncmp(str, ":autoextend", (sizeof ":autoextend") - 1)) {
|
||||||
|
|
||||||
*is_auto_extending = TRUE;
|
*is_auto_extending = TRUE;
|
||||||
|
|
||||||
str += (sizeof ":autoextend") - 1;
|
str += (sizeof ":autoextend") - 1;
|
||||||
|
|
||||||
if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) {
|
if (0 == strncmp(str, ":max:", (sizeof ":max:") - 1)) {
|
||||||
|
|
||||||
str += (sizeof ":max:") - 1;
|
str += (sizeof ":max:") - 1;
|
||||||
|
|
||||||
|
@ -123,19 +123,45 @@ ut_time(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
Returns system time. */
|
Returns system time.
|
||||||
|
Upon successful completion, the value 0 is returned; otherwise the
|
||||||
|
value -1 is returned and the global variable errno is set to indicate the
|
||||||
|
error. */
|
||||||
|
|
||||||
void
|
int
|
||||||
ut_usectime(
|
ut_usectime(
|
||||||
/*========*/
|
/*========*/
|
||||||
|
/* out: 0 on success, -1 otherwise */
|
||||||
ulint* sec, /* out: seconds since the Epoch */
|
ulint* sec, /* out: seconds since the Epoch */
|
||||||
ulint* ms) /* out: microseconds since the Epoch+*sec */
|
ulint* ms) /* out: microseconds since the Epoch+*sec */
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
int ret;
|
||||||
|
int errno_gettimeofday;
|
||||||
|
int i;
|
||||||
|
|
||||||
ut_gettimeofday(&tv, NULL);
|
for (i = 0; i < 10; i++) {
|
||||||
*sec = (ulint) tv.tv_sec;
|
|
||||||
*ms = (ulint) tv.tv_usec;
|
ret = ut_gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
errno_gettimeofday = errno;
|
||||||
|
ut_print_timestamp(stderr);
|
||||||
|
fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
|
||||||
|
strerror(errno_gettimeofday));
|
||||||
|
os_thread_sleep(100000); /* 0.1 sec */
|
||||||
|
errno = errno_gettimeofday;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != -1) {
|
||||||
|
*sec = (ulint) tv.tv_sec;
|
||||||
|
*ms = (ulint) tv.tv_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
|
@ -122,11 +122,11 @@ static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b)
|
|||||||
|
|
||||||
static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
|
static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
|
||||||
{
|
{
|
||||||
/* ORDER BY word DESC, ndepth DESC */
|
/* ORDER BY word, ndepth */
|
||||||
int i= mi_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1,
|
int i= mi_compare_text(cs, (uchar*) (*a)->word + 1, (*a)->len - 1,
|
||||||
(uchar*) (*a)->word+1,(*a)->len-1,0,0);
|
(uchar*) (*b)->word + 1, (*b)->len - 1, 0, 0);
|
||||||
if (!i)
|
if (!i)
|
||||||
i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
|
i= CMP_NUM((*a)->ndepth, (*b)->ndepth);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,23 +674,49 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
|
|||||||
(byte *) end, &word, TRUE))
|
(byte *) end, &word, TRUE))
|
||||||
{
|
{
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
|
/*
|
||||||
|
Find right-most element in the array of query words matching this
|
||||||
|
word from a document.
|
||||||
|
*/
|
||||||
for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
|
for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
|
||||||
{
|
{
|
||||||
ftbw=ftb->list[c];
|
ftbw=ftb->list[c];
|
||||||
if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len,
|
if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len,
|
||||||
(uchar*) ftbw->word+1, ftbw->len-1,
|
(uchar*) ftbw->word+1, ftbw->len-1,
|
||||||
(my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0) >0)
|
(my_bool) (ftbw->flags & FTB_FLAG_TRUNC), 0) < 0)
|
||||||
b=c;
|
b=c;
|
||||||
else
|
else
|
||||||
a=c;
|
a=c;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
If there were no words with truncation operator, we iterate to the
|
||||||
|
beginning of an array until array element is equal to the word from
|
||||||
|
a document. This is done mainly because the same word may be
|
||||||
|
mentioned twice (or more) in the query.
|
||||||
|
|
||||||
|
In case query has words with truncation operator we must iterate
|
||||||
|
to the beginning of the array. There may be non-matching query words
|
||||||
|
between matching word with truncation operator and the right-most
|
||||||
|
matching element. E.g., if we're looking for 'aaa15' in an array of
|
||||||
|
'aaa1* aaa14 aaa15 aaa16'.
|
||||||
|
|
||||||
|
Worse of that there still may be match even if the binary search
|
||||||
|
above didn't find matching element. E.g., if we're looking for
|
||||||
|
'aaa15' in an array of 'aaa1* aaa14 aaa16'. The binary search will
|
||||||
|
stop at 'aaa16'.
|
||||||
|
*/
|
||||||
for (; c>=0; c--)
|
for (; c>=0; c--)
|
||||||
{
|
{
|
||||||
ftbw=ftb->list[c];
|
ftbw=ftb->list[c];
|
||||||
if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len,
|
if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len,
|
||||||
(uchar*) ftbw->word+1,ftbw->len-1,
|
(uchar*) ftbw->word+1,ftbw->len-1,
|
||||||
(my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0))
|
(my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0))
|
||||||
break;
|
{
|
||||||
|
if (ftb->with_scan & FTB_FLAG_TRUNC)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (ftbw->docid[1] == docid)
|
if (ftbw->docid[1] == docid)
|
||||||
continue;
|
continue;
|
||||||
ftbw->docid[1]=docid;
|
ftbw->docid[1]=docid;
|
||||||
|
@ -1508,15 +1508,21 @@ sub executable_setup_ndb () {
|
|||||||
"$glob_basedir/storage/ndb",
|
"$glob_basedir/storage/ndb",
|
||||||
"$glob_basedir/bin");
|
"$glob_basedir/bin");
|
||||||
|
|
||||||
|
# Some might be found in sbin, not bin.
|
||||||
|
my $daemon_path= mtr_file_exists("$glob_basedir/ndb",
|
||||||
|
"$glob_basedir/storage/ndb",
|
||||||
|
"$glob_basedir/sbin",
|
||||||
|
"$glob_basedir/bin");
|
||||||
|
|
||||||
$exe_ndbd=
|
$exe_ndbd=
|
||||||
mtr_exe_maybe_exists("$ndb_path/src/kernel/ndbd",
|
mtr_exe_maybe_exists("$ndb_path/src/kernel/ndbd",
|
||||||
"$ndb_path/ndbd");
|
"$daemon_path/ndbd");
|
||||||
$exe_ndb_mgm=
|
$exe_ndb_mgm=
|
||||||
mtr_exe_maybe_exists("$ndb_path/src/mgmclient/ndb_mgm",
|
mtr_exe_maybe_exists("$ndb_path/src/mgmclient/ndb_mgm",
|
||||||
"$ndb_path/ndb_mgm");
|
"$ndb_path/ndb_mgm");
|
||||||
$exe_ndb_mgmd=
|
$exe_ndb_mgmd=
|
||||||
mtr_exe_maybe_exists("$ndb_path/src/mgmsrv/ndb_mgmd",
|
mtr_exe_maybe_exists("$ndb_path/src/mgmsrv/ndb_mgmd",
|
||||||
"$ndb_path/ndb_mgmd");
|
"$daemon_path/ndb_mgmd");
|
||||||
$exe_ndb_waiter=
|
$exe_ndb_waiter=
|
||||||
mtr_exe_maybe_exists("$ndb_path/tools/ndb_waiter",
|
mtr_exe_maybe_exists("$ndb_path/tools/ndb_waiter",
|
||||||
"$ndb_path/ndb_waiter");
|
"$ndb_path/ndb_waiter");
|
||||||
@ -2380,13 +2386,7 @@ sub setup_vardir() {
|
|||||||
{
|
{
|
||||||
# on windows, copy all files from std_data into var/std_data_ln
|
# on windows, copy all files from std_data into var/std_data_ln
|
||||||
mkpath("$opt_vardir/std_data_ln");
|
mkpath("$opt_vardir/std_data_ln");
|
||||||
opendir(DIR, "$glob_mysql_test_dir/std_data")
|
mtr_copy_dir("$glob_mysql_test_dir/std_data", "$opt_vardir/std_data_ln");
|
||||||
or mtr_error("Can't find the std_data directory: $!");
|
|
||||||
for(readdir(DIR)) {
|
|
||||||
next if -d "$glob_mysql_test_dir/std_data/$_";
|
|
||||||
copy("$glob_mysql_test_dir/std_data/$_", "$opt_vardir/std_data_ln/$_");
|
|
||||||
}
|
|
||||||
closedir(DIR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove old log files
|
# Remove old log files
|
||||||
|
@ -915,3 +915,19 @@ check table t1;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a tinytext character set latin1);
|
||||||
|
alter table t1 convert to character set utf8;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` text
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a mediumtext character set latin1);
|
||||||
|
alter table t1 convert to character set utf8;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` longtext
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8
|
||||||
|
drop table t1;
|
||||||
|
@ -21,6 +21,7 @@ flush logs;
|
|||||||
*** must be a warning master-bin.000001 was not found ***
|
*** must be a warning master-bin.000001 was not found ***
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1477 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found
|
Warning 1477 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found
|
||||||
|
Warning 1477 Being purged log MYSQLTEST_VARDIR/log/master-bin.000001 was not found
|
||||||
*** must show one record, of the active binlog, left in the index file after PURGE ***
|
*** must show one record, of the active binlog, left in the index file after PURGE ***
|
||||||
show binary logs;
|
show binary logs;
|
||||||
Log_name File_size
|
Log_name File_size
|
||||||
|
@ -5071,4 +5071,19 @@ select * from t1;
|
|||||||
a
|
a
|
||||||
foo
|
foo
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table bug39616_1(id int NOT NULL, d varchar(50) NOT NULL) ENGINE=csv;
|
||||||
|
select * from bug39616_1;
|
||||||
|
id d
|
||||||
|
1 integer sans quotes
|
||||||
|
1 string sans quotes
|
||||||
|
1 string end quotes"
|
||||||
|
1 quotes"in between" strings
|
||||||
|
1 Integer with quote and string with no quote
|
||||||
|
1 escape sequence
|
||||||
|
" \
\a within quotes
|
||||||
|
drop table bug39616_1;
|
||||||
|
create table bug39616_1(id int NOT NULL, d varchar(50) NOT NULL) ENGINE=csv;
|
||||||
|
select * from bug39616_1;
|
||||||
|
id d
|
||||||
|
drop table bug39616_1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -1111,4 +1111,57 @@ set names latin1;
|
|||||||
select hex(char(0x41 using ucs2));
|
select hex(char(0x41 using ucs2));
|
||||||
hex(char(0x41 using ucs2))
|
hex(char(0x41 using ucs2))
|
||||||
0041
|
0041
|
||||||
|
SET character_set_connection=ucs2;
|
||||||
|
SELECT CHARSET(DAYNAME(19700101));
|
||||||
|
CHARSET(DAYNAME(19700101))
|
||||||
|
ucs2
|
||||||
|
SELECT CHARSET(MONTHNAME(19700101));
|
||||||
|
CHARSET(MONTHNAME(19700101))
|
||||||
|
ucs2
|
||||||
|
SELECT LOWER(DAYNAME(19700101));
|
||||||
|
LOWER(DAYNAME(19700101))
|
||||||
|
thursday
|
||||||
|
SELECT LOWER(MONTHNAME(19700101));
|
||||||
|
LOWER(MONTHNAME(19700101))
|
||||||
|
january
|
||||||
|
SELECT UPPER(DAYNAME(19700101));
|
||||||
|
UPPER(DAYNAME(19700101))
|
||||||
|
THURSDAY
|
||||||
|
SELECT UPPER(MONTHNAME(19700101));
|
||||||
|
UPPER(MONTHNAME(19700101))
|
||||||
|
JANUARY
|
||||||
|
SELECT HEX(MONTHNAME(19700101));
|
||||||
|
HEX(MONTHNAME(19700101))
|
||||||
|
004A0061006E0075006100720079
|
||||||
|
SELECT HEX(DAYNAME(19700101));
|
||||||
|
HEX(DAYNAME(19700101))
|
||||||
|
00540068007500720073006400610079
|
||||||
|
SET LC_TIME_NAMES=ru_RU;
|
||||||
|
SET NAMES utf8;
|
||||||
|
SET character_set_connection=ucs2;
|
||||||
|
SELECT CHARSET(DAYNAME(19700101));
|
||||||
|
CHARSET(DAYNAME(19700101))
|
||||||
|
ucs2
|
||||||
|
SELECT CHARSET(MONTHNAME(19700101));
|
||||||
|
CHARSET(MONTHNAME(19700101))
|
||||||
|
ucs2
|
||||||
|
SELECT LOWER(DAYNAME(19700101));
|
||||||
|
LOWER(DAYNAME(19700101))
|
||||||
|
четверг
|
||||||
|
SELECT LOWER(MONTHNAME(19700101));
|
||||||
|
LOWER(MONTHNAME(19700101))
|
||||||
|
января
|
||||||
|
SELECT UPPER(DAYNAME(19700101));
|
||||||
|
UPPER(DAYNAME(19700101))
|
||||||
|
ЧЕТВЕРГ
|
||||||
|
SELECT UPPER(MONTHNAME(19700101));
|
||||||
|
UPPER(MONTHNAME(19700101))
|
||||||
|
ЯНВАРЯ
|
||||||
|
SELECT HEX(MONTHNAME(19700101));
|
||||||
|
HEX(MONTHNAME(19700101))
|
||||||
|
042F043D043204300440044F
|
||||||
|
SELECT HEX(DAYNAME(19700101));
|
||||||
|
HEX(DAYNAME(19700101))
|
||||||
|
0427043504420432043504400433
|
||||||
|
SET character_set_connection=latin1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -107,3 +107,51 @@ X X X X X X X X X
|
|||||||
X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF)
|
X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF)
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(a INT);
|
||||||
|
CREATE TABLE t2(a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
INSERT INTO t2 VALUES (1),(2);
|
||||||
|
EXPLAIN EXTENDED SELECT 1
|
||||||
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
|
||||||
|
EXPLAIN EXTENDED SELECT 1
|
||||||
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
|
||||||
|
prepare s1 from
|
||||||
|
'EXPLAIN EXTENDED SELECT 1
|
||||||
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
|
||||||
|
execute s1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
|
||||||
|
prepare s1 from
|
||||||
|
'EXPLAIN EXTENDED SELECT 1
|
||||||
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
|
||||||
|
execute s1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
|
||||||
|
execute s1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
@ -497,3 +497,12 @@ WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
|
|||||||
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 SIMPLE t1 ref b b 5 const 4 Using where
|
1 SIMPLE t1 ref b b 5 const 4 Using where
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(a CHAR(10));
|
||||||
|
INSERT INTO t1 VALUES('aaa15');
|
||||||
|
SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1;
|
||||||
|
MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE)
|
||||||
|
1
|
||||||
|
SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1;
|
||||||
|
MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE)
|
||||||
|
2
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -176,4 +176,13 @@ IF((ROUND(t1.a,2)=1), 2,
|
|||||||
IF((ROUND(t1.a,2)=1), 2,
|
IF((ROUND(t1.a,2)=1), 2,
|
||||||
IF((R
|
IF((R
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c LONGTEXT);
|
||||||
|
INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890');
|
||||||
|
SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te;
|
||||||
|
MAX(IF(1, CAST(c AS UNSIGNED), 0))
|
||||||
|
12345678901234567890
|
||||||
|
SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te;
|
||||||
|
MAX(IFNULL(CAST(c AS UNSIGNED), 0))
|
||||||
|
12345678901234567890
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -717,8 +717,6 @@ insert(_latin2'abcd',2,3,_latin2'ef'),
|
|||||||
replace(_latin2'abcd',_latin2'b',_latin2'B'),
|
replace(_latin2'abcd',_latin2'b',_latin2'B'),
|
||||||
encode('abcd','ab')
|
encode('abcd','ab')
|
||||||
;
|
;
|
||||||
Warnings:
|
|
||||||
Warning 1265 Data truncated for column 'format(130,10)' at row 1
|
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
@ -727,7 +725,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
`conv(130,16,10)` varchar(64) default NULL,
|
`conv(130,16,10)` varchar(64) default NULL,
|
||||||
`hex(130)` varchar(6) NOT NULL default '',
|
`hex(130)` varchar(6) NOT NULL default '',
|
||||||
`char(130)` varbinary(4) NOT NULL default '',
|
`char(130)` varbinary(4) NOT NULL default '',
|
||||||
`format(130,10)` varchar(4) NOT NULL default '',
|
`format(130,10)` varchar(16) NOT NULL default '',
|
||||||
`left(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '',
|
`left(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '',
|
||||||
`right(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '',
|
`right(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '',
|
||||||
`lcase(_latin2'a')` varchar(1) character set latin2 NOT NULL default '',
|
`lcase(_latin2'a')` varchar(1) character set latin2 NOT NULL default '',
|
||||||
@ -2175,4 +2173,12 @@ SELECT HEX(c1) from v1;
|
|||||||
HEX(c1)
|
HEX(c1)
|
||||||
414243
|
414243
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
|
create table t1(a float);
|
||||||
|
insert into t1 values (1.33);
|
||||||
|
select format(a, 2) from t1;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def format(a, 2) 253 20 4 Y 0 2 8
|
||||||
|
format(a, 2)
|
||||||
|
1.33
|
||||||
|
drop table t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -592,6 +592,21 @@ unix_timestamp('1970-01-01 03:00:01')
|
|||||||
select unix_timestamp('2038-01-19 07:14:07');
|
select unix_timestamp('2038-01-19 07:14:07');
|
||||||
unix_timestamp('2038-01-19 07:14:07')
|
unix_timestamp('2038-01-19 07:14:07')
|
||||||
0
|
0
|
||||||
|
SELECT CHARSET(DAYNAME(19700101));
|
||||||
|
CHARSET(DAYNAME(19700101))
|
||||||
|
latin1
|
||||||
|
SELECT CHARSET(MONTHNAME(19700101));
|
||||||
|
CHARSET(MONTHNAME(19700101))
|
||||||
|
latin1
|
||||||
|
SELECT LOWER(DAYNAME(19700101));
|
||||||
|
LOWER(DAYNAME(19700101))
|
||||||
|
thursday
|
||||||
|
SELECT LOWER(MONTHNAME(19700101));
|
||||||
|
LOWER(MONTHNAME(19700101))
|
||||||
|
january
|
||||||
|
SELECT COERCIBILITY(MONTHNAME('1970-01-01')),COERCIBILITY(DAYNAME('1970-01-01'));
|
||||||
|
COERCIBILITY(MONTHNAME('1970-01-01')) COERCIBILITY(DAYNAME('1970-01-01'))
|
||||||
|
4 4
|
||||||
CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time);
|
CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time);
|
||||||
INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08");
|
INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08");
|
||||||
SELECT * from t1;
|
SELECT * from t1;
|
||||||
|
@ -1151,4 +1151,9 @@ drop user 'greg'@'localhost';
|
|||||||
drop view v1;
|
drop view v1;
|
||||||
drop table test;
|
drop table test;
|
||||||
drop function test_function;
|
drop function test_function;
|
||||||
|
SELECT CURRENT_USER();
|
||||||
|
CURRENT_USER()
|
||||||
|
root@localhost
|
||||||
|
SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin");
|
||||||
|
SET PASSWORD FOR CURRENT_USER() = PASSWORD("");
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -527,4 +527,32 @@ b a
|
|||||||
y
|
y
|
||||||
z
|
z
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# BUG#40974: Incorrect query results when using clause evaluated using range check
|
||||||
|
#
|
||||||
|
create table t0 (a int);
|
||||||
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
create table t1 (a int);
|
||||||
|
insert into t1 values (1),(2);
|
||||||
|
create table t2(a int, b int);
|
||||||
|
insert into t2 values (1,1), (2, 1000);
|
||||||
|
create table t3 (a int, b int, filler char(100), key(a), key(b));
|
||||||
|
insert into t3 select 1000, 1000,'filler' from t0 A, t0 B, t0 C;
|
||||||
|
insert into t3 values (1,1,'data');
|
||||||
|
insert into t3 values (1,1,'data');
|
||||||
|
The plan should be ALL/ALL/ALL(Range checked for each record (index map: 0x3)
|
||||||
|
explain select * from t1
|
||||||
|
where exists (select 1 from t2, t3
|
||||||
|
where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
|
||||||
|
2 DEPENDENT SUBQUERY t3 ALL a,b NULL NULL NULL 1002 Range checked for each record (index map: 0x3)
|
||||||
|
select * from t1
|
||||||
|
where exists (select 1 from t2, t3
|
||||||
|
where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1));
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
drop table t0, t1, t2, t3;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -180,4 +180,10 @@ ERROR at line 1: DELIMITER cannot contain a backslash character
|
|||||||
1
|
1
|
||||||
This is a file starting with UTF8 BOM 0xEFBBBF
|
This is a file starting with UTF8 BOM 0xEFBBBF
|
||||||
This is a file starting with UTF8 BOM 0xEFBBBF
|
This is a file starting with UTF8 BOM 0xEFBBBF
|
||||||
|
delimiter
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -23,39 +23,9 @@ SET @@global.max_allowed_packet=4096;
|
|||||||
SET @@global.net_buffer_length=4096;
|
SET @@global.net_buffer_length=4096;
|
||||||
STOP SLAVE;
|
STOP SLAVE;
|
||||||
START SLAVE;
|
START SLAVE;
|
||||||
CREATE TABLe `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
|
CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
|
||||||
INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
|
INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
|
||||||
show slave status;
|
Slave_IO_Running = No (expect No)
|
||||||
Slave_IO_State #
|
==== clean up ====
|
||||||
Master_Host 127.0.0.1
|
DROP TABLE t1;
|
||||||
Master_User root
|
DROP TABLE t1;
|
||||||
Master_Port MASTER_MYPORT
|
|
||||||
Connect_Retry 1
|
|
||||||
Master_Log_File master-bin.000001
|
|
||||||
Read_Master_Log_Pos 2138
|
|
||||||
Relay_Log_File #
|
|
||||||
Relay_Log_Pos #
|
|
||||||
Relay_Master_Log_File master-bin.000001
|
|
||||||
Slave_IO_Running No
|
|
||||||
Slave_SQL_Running #
|
|
||||||
Replicate_Do_DB
|
|
||||||
Replicate_Ignore_DB
|
|
||||||
Replicate_Do_Table
|
|
||||||
Replicate_Ignore_Table
|
|
||||||
Replicate_Wild_Do_Table
|
|
||||||
Replicate_Wild_Ignore_Table
|
|
||||||
Last_Errno 0
|
|
||||||
Last_Error
|
|
||||||
Skip_Counter 0
|
|
||||||
Exec_Master_Log_Pos 2138
|
|
||||||
Relay_Log_Space #
|
|
||||||
Until_Condition None
|
|
||||||
Until_Log_File
|
|
||||||
Until_Log_Pos 0
|
|
||||||
Master_SSL_Allowed No
|
|
||||||
Master_SSL_CA_File
|
|
||||||
Master_SSL_CA_Path
|
|
||||||
Master_SSL_Cert
|
|
||||||
Master_SSL_Cipher
|
|
||||||
Master_SSL_Key
|
|
||||||
Seconds_Behind_Master #
|
|
||||||
|
@ -4355,4 +4355,37 @@ Handler_read_prev 0
|
|||||||
Handler_read_rnd 0
|
Handler_read_rnd 0
|
||||||
Handler_read_rnd_next 6
|
Handler_read_rnd_next 6
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0',
|
||||||
|
f2 int(11) NOT NULL default '0',
|
||||||
|
f3 bigint(20) NOT NULL default '0',
|
||||||
|
f4 varchar(255) NOT NULL default '',
|
||||||
|
PRIMARY KEY (f1),
|
||||||
|
KEY key1 (f4),
|
||||||
|
KEY key2 (f2));
|
||||||
|
CREATE TABLE t2 (f1 int(11) NOT NULL default '0',
|
||||||
|
f2 enum('A1','A2','A3') NOT NULL default 'A1',
|
||||||
|
f3 int(11) NOT NULL default '0',
|
||||||
|
PRIMARY KEY (f1),
|
||||||
|
KEY key1 (f3));
|
||||||
|
CREATE TABLE t3 (f1 bigint(20) NOT NULL default '0',
|
||||||
|
f2 datetime NOT NULL default '1980-01-01 00:00:00',
|
||||||
|
PRIMARY KEY (f1));
|
||||||
|
insert into t1 values (1, 1, 1, 'abc');
|
||||||
|
insert into t1 values (2, 1, 2, 'def');
|
||||||
|
insert into t1 values (3, 1, 2, 'def');
|
||||||
|
insert into t2 values (1, 'A1', 1);
|
||||||
|
insert into t3 values (1, '1980-01-01');
|
||||||
|
SELECT a.f3, cr.f4, count(*) count
|
||||||
|
FROM t2 a
|
||||||
|
STRAIGHT_JOIN t1 cr ON cr.f2 = a.f1
|
||||||
|
LEFT JOIN
|
||||||
|
(t1 cr2
|
||||||
|
JOIN t3 ae2 ON cr2.f3 = ae2.f1
|
||||||
|
) ON a.f1 = cr2.f2 AND ae2.f2 < now() - INTERVAL 7 DAY AND
|
||||||
|
cr.f4 = cr2.f4
|
||||||
|
GROUP BY a.f3, cr.f4;
|
||||||
|
f3 f4 count
|
||||||
|
1 abc 1
|
||||||
|
1 def 2
|
||||||
|
drop table t1, t2, t3;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -91,3 +91,28 @@ SHOW SESSION STATUS LIKE 'Last_query_cost';
|
|||||||
Variable_name Value
|
Variable_name Value
|
||||||
Last_query_cost 4.805836
|
Last_query_cost 4.805836
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
CREATE FUNCTION f1() RETURNS INTEGER
|
||||||
|
BEGIN
|
||||||
|
DECLARE foo INTEGER;
|
||||||
|
DECLARE bar INTEGER;
|
||||||
|
SET foo=1;
|
||||||
|
SET bar=2;
|
||||||
|
RETURN foo;
|
||||||
|
END $$
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
SELECT 1;
|
||||||
|
END $$
|
||||||
|
SELECT f1();
|
||||||
|
f1()
|
||||||
|
1
|
||||||
|
CALL p1();
|
||||||
|
1
|
||||||
|
1
|
||||||
|
SELECT 9;
|
||||||
|
9
|
||||||
|
9
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
@ -1348,6 +1348,13 @@ t1 CREATE TABLE `t1` (
|
|||||||
`i` int(11) default NULL
|
`i` int(11) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*'
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*'
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן';
|
||||||
|
SHOW CREATE TABLE t3;
|
||||||
|
Table Create Table
|
||||||
|
t3 CREATE TABLE `t3` (
|
||||||
|
`f1` int(11) default NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'
|
||||||
|
DROP TABLE t3;
|
||||||
set sql_mode= 'traditional';
|
set sql_mode= 'traditional';
|
||||||
create table t1(col1 tinyint, col2 tinyint unsigned,
|
create table t1(col1 tinyint, col2 tinyint unsigned,
|
||||||
col3 smallint, col4 smallint unsigned,
|
col3 smallint, col4 smallint unsigned,
|
||||||
|
@ -708,4 +708,45 @@ HEX(b1) HEX(b2) i2
|
|||||||
1 0 100
|
1 0 100
|
||||||
1 0 200
|
1 0 200
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE IF NOT EXISTS t1 (
|
||||||
|
f1 bit(2) NOT NULL default b'10',
|
||||||
|
f2 bit(14) NOT NULL default b'11110000111100'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`f1` bit(2) NOT NULL default b'10',
|
||||||
|
`f2` bit(14) NOT NULL default b'11110000111100'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE IF NOT EXISTS t1 (
|
||||||
|
f1 bit(2) NOT NULL default b''
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
|
||||||
|
ERROR 42000: Invalid default value for 'f1'
|
||||||
|
create table t1bit7 (a1 bit(7) not null) engine=MyISAM;
|
||||||
|
create table t2bit7 (b1 bit(7)) engine=MyISAM;
|
||||||
|
insert into t1bit7 values (b'1100000');
|
||||||
|
insert into t1bit7 values (b'1100001');
|
||||||
|
insert into t1bit7 values (b'1100010');
|
||||||
|
insert into t2bit7 values (b'1100001');
|
||||||
|
insert into t2bit7 values (b'1100010');
|
||||||
|
insert into t2bit7 values (b'1100110');
|
||||||
|
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
|
||||||
|
bin(a1)
|
||||||
|
1100001
|
||||||
|
1100010
|
||||||
|
drop table t1bit7, t2bit7;
|
||||||
|
create table t1bit7 (a1 bit(15) not null) engine=MyISAM;
|
||||||
|
create table t2bit7 (b1 bit(15)) engine=MyISAM;
|
||||||
|
insert into t1bit7 values (b'110000011111111');
|
||||||
|
insert into t1bit7 values (b'110000111111111');
|
||||||
|
insert into t1bit7 values (b'110001011111111');
|
||||||
|
insert into t2bit7 values (b'110000111111111');
|
||||||
|
insert into t2bit7 values (b'110001011111111');
|
||||||
|
insert into t2bit7 values (b'110011011111111');
|
||||||
|
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
|
||||||
|
bin(a1)
|
||||||
|
110000111111111
|
||||||
|
110001011111111
|
||||||
|
drop table t1bit7, t2bit7;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -392,4 +392,13 @@ f1 + 0e0
|
|||||||
1.0000000150475e+30
|
1.0000000150475e+30
|
||||||
-1.0000000150475e+30
|
-1.0000000150475e+30
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1(d double, u bigint unsigned);
|
||||||
|
insert into t1(d) values (9.22337203685479e18),
|
||||||
|
(1.84e19);
|
||||||
|
update t1 set u = d;
|
||||||
|
select u from t1;
|
||||||
|
u
|
||||||
|
9223372036854790144
|
||||||
|
18400000000000000000
|
||||||
|
drop table t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -696,3 +696,16 @@ unlock tables;
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
check table t1;
|
check table t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#31291 ALTER TABLE CONVERT TO CHARACTER SET does not change some data types
|
||||||
|
#
|
||||||
|
create table t1 (a tinytext character set latin1);
|
||||||
|
alter table t1 convert to character set utf8;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (a mediumtext character set latin1);
|
||||||
|
alter table t1 convert to character set utf8;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
@ -1460,4 +1460,47 @@ insert into t1 values();
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #39616 Missing quotes from .CSV crashes server
|
||||||
|
#
|
||||||
|
# Editing the .CSV file and leaving out quotes from around an integer field
|
||||||
|
# crashes the server.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for the integers and strings enclosed in quotes, not enclosed in quotes,
|
||||||
|
# \X characters.
|
||||||
|
#
|
||||||
|
create table bug39616_1(id int NOT NULL, d varchar(50) NOT NULL) ENGINE=csv;
|
||||||
|
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/master-data/test/bug39616_1.CSV
|
||||||
|
--write_file $MYSQLTEST_VARDIR/master-data/test/bug39616_1.CSV
|
||||||
|
1,"integer sans quotes"
|
||||||
|
1,string sans quotes
|
||||||
|
1,string end quotes"
|
||||||
|
1,quotes"in between" strings
|
||||||
|
"1",Integer with quote and string with no quote
|
||||||
|
1,"escape sequence \n \" \\ \r \a within quotes"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
select * from bug39616_1;
|
||||||
|
|
||||||
|
drop table bug39616_1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for he case when a field begins with a quote, but does not end in a
|
||||||
|
# quote.
|
||||||
|
# Note: This results in an empty set.
|
||||||
|
#
|
||||||
|
create table bug39616_1(id int NOT NULL, d varchar(50) NOT NULL) ENGINE=csv;
|
||||||
|
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/master-data/test/bug39616_1.CSV
|
||||||
|
--write_file $MYSQLTEST_VARDIR/master-data/test/bug39616_1.CSV
|
||||||
|
1,"string only at the beginning quotes
|
||||||
|
EOF
|
||||||
|
|
||||||
|
select * from bug39616_1;
|
||||||
|
|
||||||
|
drop table bug39616_1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -685,4 +685,29 @@ set names latin1;
|
|||||||
#
|
#
|
||||||
select hex(char(0x41 using ucs2));
|
select hex(char(0x41 using ucs2));
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#37575: UCASE fails on monthname
|
||||||
|
#
|
||||||
|
SET character_set_connection=ucs2;
|
||||||
|
SELECT CHARSET(DAYNAME(19700101));
|
||||||
|
SELECT CHARSET(MONTHNAME(19700101));
|
||||||
|
SELECT LOWER(DAYNAME(19700101));
|
||||||
|
SELECT LOWER(MONTHNAME(19700101));
|
||||||
|
SELECT UPPER(DAYNAME(19700101));
|
||||||
|
SELECT UPPER(MONTHNAME(19700101));
|
||||||
|
SELECT HEX(MONTHNAME(19700101));
|
||||||
|
SELECT HEX(DAYNAME(19700101));
|
||||||
|
SET LC_TIME_NAMES=ru_RU;
|
||||||
|
SET NAMES utf8;
|
||||||
|
SET character_set_connection=ucs2;
|
||||||
|
SELECT CHARSET(DAYNAME(19700101));
|
||||||
|
SELECT CHARSET(MONTHNAME(19700101));
|
||||||
|
SELECT LOWER(DAYNAME(19700101));
|
||||||
|
SELECT LOWER(MONTHNAME(19700101));
|
||||||
|
SELECT UPPER(DAYNAME(19700101));
|
||||||
|
SELECT UPPER(MONTHNAME(19700101));
|
||||||
|
SELECT HEX(MONTHNAME(19700101));
|
||||||
|
SELECT HEX(DAYNAME(19700101));
|
||||||
|
SET character_set_connection=latin1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -94,4 +94,33 @@ EXPLAIN SELECT 1 FROM
|
|||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #34773: query with explain extended and derived table / other table
|
||||||
|
# crashes server
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1(a INT);
|
||||||
|
CREATE TABLE t2(a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
INSERT INTO t2 VALUES (1),(2);
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED SELECT 1
|
||||||
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED SELECT 1
|
||||||
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
|
||||||
|
|
||||||
|
prepare s1 from
|
||||||
|
'EXPLAIN EXTENDED SELECT 1
|
||||||
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
|
||||||
|
execute s1;
|
||||||
|
|
||||||
|
prepare s1 from
|
||||||
|
'EXPLAIN EXTENDED SELECT 1
|
||||||
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
|
||||||
|
execute s1;
|
||||||
|
execute s1;
|
||||||
|
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
# End of 5.0 tests.
|
# End of 5.0 tests.
|
||||||
|
@ -423,3 +423,12 @@ EXPLAIN SELECT * FROM t1 FORCE INDEX(b)
|
|||||||
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
|
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#37245 - Full text search problem
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a CHAR(10));
|
||||||
|
INSERT INTO t1 VALUES('aaa15');
|
||||||
|
SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1;
|
||||||
|
SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -150,4 +150,18 @@ FROM t1;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #40761: Assert on sum func on IF(..., CAST(longtext AS UNSIGNED), signed)
|
||||||
|
# (was: LEFT JOIN on inline view crashes server)
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (c LONGTEXT);
|
||||||
|
INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890');
|
||||||
|
|
||||||
|
SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te;
|
||||||
|
SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -1149,4 +1149,14 @@ CREATE VIEW v1 AS SELECT CHAR(0x414243) as c1;
|
|||||||
SELECT HEX(c1) from v1;
|
SELECT HEX(c1) from v1;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #35558 Wrong server metadata blows up the client
|
||||||
|
#
|
||||||
|
create table t1(a float);
|
||||||
|
insert into t1 values (1.33);
|
||||||
|
--enable_metadata
|
||||||
|
select format(a, 2) from t1;
|
||||||
|
--disable_metadata
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -304,6 +304,15 @@ select unix_timestamp('1970-01-01 03:00:01');
|
|||||||
# check bad date, close to the boundary (we cut them off in the very end)
|
# check bad date, close to the boundary (we cut them off in the very end)
|
||||||
select unix_timestamp('2038-01-19 07:14:07');
|
select unix_timestamp('2038-01-19 07:14:07');
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #28759: DAYNAME() and MONTHNAME() return binary string
|
||||||
|
#
|
||||||
|
|
||||||
|
SELECT CHARSET(DAYNAME(19700101));
|
||||||
|
SELECT CHARSET(MONTHNAME(19700101));
|
||||||
|
SELECT LOWER(DAYNAME(19700101));
|
||||||
|
SELECT LOWER(MONTHNAME(19700101));
|
||||||
|
SELECT COERCIBILITY(MONTHNAME('1970-01-01')),COERCIBILITY(DAYNAME('1970-01-01'));
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test types from + INTERVAL
|
# Test types from + INTERVAL
|
||||||
|
@ -1175,4 +1175,11 @@ drop view v1;
|
|||||||
drop table test;
|
drop table test;
|
||||||
drop function test_function;
|
drop function test_function;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#41456 SET PASSWORD hates CURRENT_USER()
|
||||||
|
#
|
||||||
|
SELECT CURRENT_USER();
|
||||||
|
SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin");
|
||||||
|
SET PASSWORD FOR CURRENT_USER() = PASSWORD("");
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -477,4 +477,30 @@ SELECT b,a from t1 WHERE (b!='c' AND b!='f' && b!='h') OR
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#40974: Incorrect query results when using clause evaluated using range check
|
||||||
|
--echo #
|
||||||
|
create table t0 (a int);
|
||||||
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
|
||||||
|
create table t1 (a int);
|
||||||
|
insert into t1 values (1),(2);
|
||||||
|
create table t2(a int, b int);
|
||||||
|
insert into t2 values (1,1), (2, 1000);
|
||||||
|
create table t3 (a int, b int, filler char(100), key(a), key(b));
|
||||||
|
|
||||||
|
insert into t3 select 1000, 1000,'filler' from t0 A, t0 B, t0 C;
|
||||||
|
insert into t3 values (1,1,'data');
|
||||||
|
insert into t3 values (1,1,'data');
|
||||||
|
-- echo The plan should be ALL/ALL/ALL(Range checked for each record (index map: 0x3)
|
||||||
|
explain select * from t1
|
||||||
|
where exists (select 1 from t2, t3
|
||||||
|
where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1));
|
||||||
|
|
||||||
|
select * from t1
|
||||||
|
where exists (select 1 from t2, t3
|
||||||
|
where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1));
|
||||||
|
|
||||||
|
drop table t0, t1, t2, t3;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -290,4 +290,23 @@ EOF
|
|||||||
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug29323.sql 2>&1
|
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug29323.sql 2>&1
|
||||||
remove_file $MYSQLTEST_VARDIR/tmp/bug29323.sql;
|
remove_file $MYSQLTEST_VARDIR/tmp/bug29323.sql;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #33812: mysql client incorrectly parsing DELIMITER
|
||||||
|
#
|
||||||
|
# The space and ; after delimiter are important
|
||||||
|
--exec $MYSQL -e "select 1 delimiter ;"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #38158: mysql client regression, can't read dump files
|
||||||
|
#
|
||||||
|
--write_file $MYSQLTEST_VARDIR/tmp/bug38158.sql
|
||||||
|
-- Testing
|
||||||
|
--
|
||||||
|
delimiter ||
|
||||||
|
select 2 ||
|
||||||
|
EOF
|
||||||
|
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug38158.sql 2>&1
|
||||||
|
--exec $MYSQL -c < $MYSQLTEST_VARDIR/tmp/bug38158.sql 2>&1
|
||||||
|
remove_file $MYSQLTEST_VARDIR/tmp/bug38158.sql;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -73,16 +73,26 @@ disconnect master;
|
|||||||
connect (master, localhost, root);
|
connect (master, localhost, root);
|
||||||
connection master;
|
connection master;
|
||||||
|
|
||||||
CREATE TABLe `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
|
CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
|
||||||
INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
|
INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
|
||||||
|
|
||||||
# The slave I/O thread must stop after trying to read the above event
|
# The slave I/O thread must stop after trying to read the above event
|
||||||
connection slave;
|
connection slave;
|
||||||
--source include/wait_for_slave_io_to_stop.inc
|
--source include/wait_for_slave_io_to_stop.inc
|
||||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
let $slave_io_running= query_get_value(SHOW SLAVE STATUS, Slave_IO_Running, 1);
|
||||||
# import is only the 11th column Slave_IO_Running
|
--echo Slave_IO_Running = $slave_io_running (expect No)
|
||||||
--replace_column 1 # 8 # 9 # 12 # 23 # 33 #
|
|
||||||
query_vertical show slave status;
|
|
||||||
|
--echo ==== clean up ====
|
||||||
|
connection master;
|
||||||
|
DROP TABLE t1;
|
||||||
|
# slave is stopped
|
||||||
|
connection slave;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
# End of tests
|
# End of tests
|
||||||
|
@ -3701,4 +3701,40 @@ SELECT DISTINCT b FROM t1 LEFT JOIN t2 USING(a) WHERE c <= 3;
|
|||||||
SHOW STATUS LIKE 'Handler_read%';
|
SHOW STATUS LIKE 'Handler_read%';
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#40953 SELECT query throws "ERROR 1062 (23000): Duplicate entry..." error
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0',
|
||||||
|
f2 int(11) NOT NULL default '0',
|
||||||
|
f3 bigint(20) NOT NULL default '0',
|
||||||
|
f4 varchar(255) NOT NULL default '',
|
||||||
|
PRIMARY KEY (f1),
|
||||||
|
KEY key1 (f4),
|
||||||
|
KEY key2 (f2));
|
||||||
|
CREATE TABLE t2 (f1 int(11) NOT NULL default '0',
|
||||||
|
f2 enum('A1','A2','A3') NOT NULL default 'A1',
|
||||||
|
f3 int(11) NOT NULL default '0',
|
||||||
|
PRIMARY KEY (f1),
|
||||||
|
KEY key1 (f3));
|
||||||
|
CREATE TABLE t3 (f1 bigint(20) NOT NULL default '0',
|
||||||
|
f2 datetime NOT NULL default '1980-01-01 00:00:00',
|
||||||
|
PRIMARY KEY (f1));
|
||||||
|
|
||||||
|
insert into t1 values (1, 1, 1, 'abc');
|
||||||
|
insert into t1 values (2, 1, 2, 'def');
|
||||||
|
insert into t1 values (3, 1, 2, 'def');
|
||||||
|
insert into t2 values (1, 'A1', 1);
|
||||||
|
insert into t3 values (1, '1980-01-01');
|
||||||
|
|
||||||
|
SELECT a.f3, cr.f4, count(*) count
|
||||||
|
FROM t2 a
|
||||||
|
STRAIGHT_JOIN t1 cr ON cr.f2 = a.f1
|
||||||
|
LEFT JOIN
|
||||||
|
(t1 cr2
|
||||||
|
JOIN t3 ae2 ON cr2.f3 = ae2.f1
|
||||||
|
) ON a.f1 = cr2.f2 AND ae2.f2 < now() - INTERVAL 7 DAY AND
|
||||||
|
cr.f4 = cr2.f4
|
||||||
|
GROUP BY a.f3, cr.f4;
|
||||||
|
|
||||||
|
drop table t1, t2, t3;
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -171,4 +171,40 @@ SHOW SESSION STATUS LIKE 'Last_query_cost';
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#41131 "Questions" fails to increment - ignores statements instead stored procs
|
||||||
|
#
|
||||||
|
connect (con1,localhost,root,,);
|
||||||
|
connection con1;
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
--enable_warnings
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE FUNCTION f1() RETURNS INTEGER
|
||||||
|
BEGIN
|
||||||
|
DECLARE foo INTEGER;
|
||||||
|
DECLARE bar INTEGER;
|
||||||
|
SET foo=1;
|
||||||
|
SET bar=2;
|
||||||
|
RETURN foo;
|
||||||
|
END $$
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
SELECT 1;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;$$
|
||||||
|
let $org_queries= `SHOW STATUS LIKE 'Queries'`;
|
||||||
|
SELECT f1();
|
||||||
|
CALL p1();
|
||||||
|
let $new_queries= `SHOW STATUS LIKE 'Queries'`;
|
||||||
|
--disable_log
|
||||||
|
let $diff= `SELECT SUBSTRING('$new_queries',9)-SUBSTRING('$org_queries',9)`;
|
||||||
|
--enable_log
|
||||||
|
eval SELECT $diff;
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
# End of 5.0 tests
|
# End of 5.0 tests
|
||||||
|
@ -1199,6 +1199,15 @@ comment '123456789*123456789*123456789*123456789*123456789*123456789*';
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #39591: Crash if table comment is longer than 62 characters
|
||||||
|
#
|
||||||
|
|
||||||
|
#60 chars, 120 (+1) bytes (UTF-8 with 2-byte chars)
|
||||||
|
CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן';
|
||||||
|
SHOW CREATE TABLE t3;
|
||||||
|
DROP TABLE t3;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #26359: Strings becoming truncated and converted to numbers under STRICT mode
|
# Bug #26359: Strings becoming truncated and converted to numbers under STRICT mode
|
||||||
#
|
#
|
||||||
|
@ -352,4 +352,49 @@ SELECT HEX(b1), HEX(b2), i2 FROM t2
|
|||||||
|
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #35796 SHOW CREATE TABLE and default value for BIT field
|
||||||
|
#
|
||||||
|
CREATE TABLE IF NOT EXISTS t1 (
|
||||||
|
f1 bit(2) NOT NULL default b'10',
|
||||||
|
f2 bit(14) NOT NULL default b'11110000111100'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--error ER_INVALID_DEFAULT
|
||||||
|
CREATE TABLE IF NOT EXISTS t1 (
|
||||||
|
f1 bit(2) NOT NULL default b''
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#31399 Wrong query result when doing join buffering over BIT fields
|
||||||
|
#
|
||||||
|
create table t1bit7 (a1 bit(7) not null) engine=MyISAM;
|
||||||
|
create table t2bit7 (b1 bit(7)) engine=MyISAM;
|
||||||
|
|
||||||
|
insert into t1bit7 values (b'1100000');
|
||||||
|
insert into t1bit7 values (b'1100001');
|
||||||
|
insert into t1bit7 values (b'1100010');
|
||||||
|
insert into t2bit7 values (b'1100001');
|
||||||
|
insert into t2bit7 values (b'1100010');
|
||||||
|
insert into t2bit7 values (b'1100110');
|
||||||
|
|
||||||
|
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
|
||||||
|
drop table t1bit7, t2bit7;
|
||||||
|
|
||||||
|
create table t1bit7 (a1 bit(15) not null) engine=MyISAM;
|
||||||
|
create table t2bit7 (b1 bit(15)) engine=MyISAM;
|
||||||
|
|
||||||
|
insert into t1bit7 values (b'110000011111111');
|
||||||
|
insert into t1bit7 values (b'110000111111111');
|
||||||
|
insert into t1bit7 values (b'110001011111111');
|
||||||
|
insert into t2bit7 values (b'110000111111111');
|
||||||
|
insert into t2bit7 values (b'110001011111111');
|
||||||
|
insert into t2bit7 values (b'110011011111111');
|
||||||
|
|
||||||
|
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
|
||||||
|
drop table t1bit7, t2bit7;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -252,4 +252,19 @@ insert into t1 values (2e30), (-2e30);
|
|||||||
select f1 + 0e0 from t1;
|
select f1 + 0e0 from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27483: Casting 'scientific notation type' to 'unsigned bigint' fails on
|
||||||
|
# windows.
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1(d double, u bigint unsigned);
|
||||||
|
|
||||||
|
insert into t1(d) values (9.22337203685479e18),
|
||||||
|
(1.84e19);
|
||||||
|
|
||||||
|
update t1 set u = d;
|
||||||
|
select u from t1;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -416,37 +416,96 @@ int ha_tina::find_current_row(byte *buf)
|
|||||||
if ((end_ptr= find_eoln(share->mapped_file, current_position, share->file_stat.st_size)) == 0)
|
if ((end_ptr= find_eoln(share->mapped_file, current_position, share->file_stat.st_size)) == 0)
|
||||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse the line obtained using the following algorithm
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
1) Store the EOL (end of line) for the current row
|
||||||
|
2) Until all the fields in the current query have not been
|
||||||
|
filled
|
||||||
|
2.1) If the current character begins with a quote
|
||||||
|
2.1.1) Until EOL has not been reached
|
||||||
|
a) If end of current field is reached, move
|
||||||
|
to next field and jump to step 2.3
|
||||||
|
b) If current character begins with \\ handle
|
||||||
|
\\n, \\r, \\, \\"
|
||||||
|
c) else append the current character into the buffer
|
||||||
|
before checking that EOL has not been reached.
|
||||||
|
2.2) If the current character does not begin with a quote
|
||||||
|
2.2.1) Until EOL has not been reached
|
||||||
|
a) If the end of field has been reached move to the
|
||||||
|
next field and jump to step 2.3
|
||||||
|
b) append the current character into the buffer
|
||||||
|
2.3) Store the current field value and jump to 2)
|
||||||
|
TERMINATE
|
||||||
|
*/
|
||||||
|
|
||||||
for (Field **field=table->field ; *field ; field++)
|
for (Field **field=table->field ; *field ; field++)
|
||||||
{
|
{
|
||||||
buffer.length(0);
|
buffer.length(0);
|
||||||
mapped_ptr++; // Increment past the first quote
|
/* Handle the case where the first character begins with a quote */
|
||||||
for(;mapped_ptr != end_ptr; mapped_ptr++)
|
if (*mapped_ptr == '"')
|
||||||
{
|
{
|
||||||
//Need to convert line feeds!
|
/* Increment past the first quote */
|
||||||
if (*mapped_ptr == '"' &&
|
mapped_ptr++;
|
||||||
(((mapped_ptr[1] == ',') && (mapped_ptr[2] == '"')) || (mapped_ptr == end_ptr -1 )))
|
/* Loop through the row to extract the values for the current field */
|
||||||
|
for(; mapped_ptr != end_ptr; mapped_ptr++)
|
||||||
{
|
{
|
||||||
mapped_ptr += 2; // Move past the , and the "
|
/* check for end of the current field */
|
||||||
break;
|
if (*mapped_ptr == '"' &&
|
||||||
}
|
(mapped_ptr[1] == ',' || mapped_ptr == end_ptr -1 ))
|
||||||
if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1))
|
|
||||||
{
|
|
||||||
mapped_ptr++;
|
|
||||||
if (*mapped_ptr == 'r')
|
|
||||||
buffer.append('\r');
|
|
||||||
else if (*mapped_ptr == 'n' )
|
|
||||||
buffer.append('\n');
|
|
||||||
else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"'))
|
|
||||||
buffer.append(*mapped_ptr);
|
|
||||||
else /* This could only happed with an externally created file */
|
|
||||||
{
|
{
|
||||||
buffer.append('\\');
|
/* Move past the , and the " */
|
||||||
|
mapped_ptr += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1))
|
||||||
|
{
|
||||||
|
mapped_ptr++;
|
||||||
|
if (*mapped_ptr == 'r')
|
||||||
|
buffer.append('\r');
|
||||||
|
else if (*mapped_ptr == 'n' )
|
||||||
|
buffer.append('\n');
|
||||||
|
else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"'))
|
||||||
|
buffer.append(*mapped_ptr);
|
||||||
|
else /* This could only happed with an externally created file */
|
||||||
|
{
|
||||||
|
buffer.append('\\');
|
||||||
|
buffer.append(*mapped_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If no last quote was found, but the end of row has been reached
|
||||||
|
it implies that there has been error.
|
||||||
|
*/
|
||||||
|
if (mapped_ptr == end_ptr -1)
|
||||||
|
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||||
|
/* Store current character in the buffer for the field */
|
||||||
buffer.append(*mapped_ptr);
|
buffer.append(*mapped_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
buffer.append(*mapped_ptr);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Handle the case where the current row does not start with quotes */
|
||||||
|
|
||||||
|
/* Loop through the row to extract the values for the current field */
|
||||||
|
for (; mapped_ptr != end_ptr; mapped_ptr++)
|
||||||
|
{
|
||||||
|
/* check for end of current field */
|
||||||
|
if (*mapped_ptr == ',')
|
||||||
|
{
|
||||||
|
/* Increment past the current comma */
|
||||||
|
mapped_ptr++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* store the current character in the buffer for the field */
|
||||||
|
buffer.append(*mapped_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Store the field value from the buffer */
|
||||||
(*field)->store(buffer.ptr(), buffer.length(), buffer.charset());
|
(*field)->store(buffer.ptr(), buffer.length(), buffer.charset());
|
||||||
}
|
}
|
||||||
next_position= (end_ptr - share->mapped_file)+1;
|
next_position= (end_ptr - share->mapped_file)+1;
|
||||||
|
@ -3473,7 +3473,7 @@ int Field_longlong::store(double nr)
|
|||||||
error= 1;
|
error= 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res=(longlong) (ulonglong) nr;
|
res=(longlong) double2ulonglong(nr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2158,6 +2158,14 @@ ha_innobase::open(
|
|||||||
UT_NOT_USED(test_if_locked);
|
UT_NOT_USED(test_if_locked);
|
||||||
|
|
||||||
thd = current_thd;
|
thd = current_thd;
|
||||||
|
|
||||||
|
/* Under some cases MySQL seems to call this function while
|
||||||
|
holding btr_search_latch. This breaks the latching order as
|
||||||
|
we acquire dict_sys->mutex below and leads to a deadlock. */
|
||||||
|
if (thd != NULL) {
|
||||||
|
innobase_release_temporary_latches(thd);
|
||||||
|
}
|
||||||
|
|
||||||
normalize_table_name(norm_name, name);
|
normalize_table_name(norm_name, name);
|
||||||
|
|
||||||
user_thd = NULL;
|
user_thd = NULL;
|
||||||
|
@ -4950,6 +4950,9 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions)
|
|||||||
|
|
||||||
ulonglong nr;
|
ulonglong nr;
|
||||||
uint32 length= str_value.length();
|
uint32 length= str_value.length();
|
||||||
|
if (!length)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (length > 8)
|
if (length > 8)
|
||||||
{
|
{
|
||||||
nr= field->flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX;
|
nr= field->flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX;
|
||||||
@ -6792,7 +6795,7 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
|
|||||||
*/
|
*/
|
||||||
Item_sum *item_sum= (Item_sum *) item;
|
Item_sum *item_sum= (Item_sum *) item;
|
||||||
if (item_sum->keep_field_type())
|
if (item_sum->keep_field_type())
|
||||||
return get_real_type(item_sum->args[0]);
|
return get_real_type(item_sum->get_arg(0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FUNC_ITEM:
|
case FUNC_ITEM:
|
||||||
@ -7056,7 +7059,7 @@ void Item_type_holder::get_full_info(Item *item)
|
|||||||
if (item->type() == Item::SUM_FUNC_ITEM &&
|
if (item->type() == Item::SUM_FUNC_ITEM &&
|
||||||
(((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC ||
|
(((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC ||
|
||||||
((Item_sum*)item)->sum_func() == Item_sum::MIN_FUNC))
|
((Item_sum*)item)->sum_func() == Item_sum::MIN_FUNC))
|
||||||
item = ((Item_sum*)item)->args[0];
|
item = ((Item_sum*)item)->get_arg(0);
|
||||||
/*
|
/*
|
||||||
We can have enum/set type after merging only if we have one enum|set
|
We can have enum/set type after merging only if we have one enum|set
|
||||||
field (or MIN|MAX(enum|set field)) and number of NULL fields
|
field (or MIN|MAX(enum|set field)) and number of NULL fields
|
||||||
|
@ -351,7 +351,10 @@ public:
|
|||||||
Item_func_unsigned(Item *a) :Item_func_signed(a) {}
|
Item_func_unsigned(Item *a) :Item_func_signed(a) {}
|
||||||
const char *func_name() const { return "cast_as_unsigned"; }
|
const char *func_name() const { return "cast_as_unsigned"; }
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec()
|
||||||
{ max_length=args[0]->max_length; unsigned_flag=1; }
|
{
|
||||||
|
max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
|
||||||
|
unsigned_flag=1;
|
||||||
|
}
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
};
|
};
|
||||||
|
@ -516,8 +516,9 @@ public:
|
|||||||
{
|
{
|
||||||
collation.set(default_charset());
|
collation.set(default_charset());
|
||||||
uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen;
|
uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen;
|
||||||
max_length= ((char_length + (char_length-args[0]->decimals)/3) *
|
uint max_sep_count= char_length/3 + (decimals ? 1 : 0) + /*sign*/1;
|
||||||
collation.collation->mbmaxlen);
|
max_length= (char_length + max_sep_count + decimals) *
|
||||||
|
collation.collation->mbmaxlen;
|
||||||
}
|
}
|
||||||
const char *func_name() const { return "format"; }
|
const char *func_name() const { return "format"; }
|
||||||
void print(String *);
|
void print(String *);
|
||||||
|
@ -370,6 +370,10 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
|
|||||||
args[i++]= item;
|
args[i++]= item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count)))
|
||||||
|
{
|
||||||
|
args= NULL;
|
||||||
|
}
|
||||||
mark_as_sum_func();
|
mark_as_sum_func();
|
||||||
list.empty(); // Fields are used
|
list.empty(); // Fields are used
|
||||||
}
|
}
|
||||||
@ -380,18 +384,28 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||||
Item_result_field(thd, item), arg_count(item->arg_count),
|
Item_result_field(thd, item),
|
||||||
aggr_sel(item->aggr_sel),
|
aggr_sel(item->aggr_sel),
|
||||||
nest_level(item->nest_level), aggr_level(item->aggr_level),
|
nest_level(item->nest_level), aggr_level(item->aggr_level),
|
||||||
quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
|
quick_group(item->quick_group),
|
||||||
|
arg_count(item->arg_count), orig_args(NULL),
|
||||||
|
used_tables_cache(item->used_tables_cache),
|
||||||
forced_const(item->forced_const)
|
forced_const(item->forced_const)
|
||||||
{
|
{
|
||||||
if (arg_count <= 2)
|
if (arg_count <= 2)
|
||||||
|
{
|
||||||
args=tmp_args;
|
args=tmp_args;
|
||||||
|
orig_args=tmp_orig_args;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
|
if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
|
||||||
return;
|
return;
|
||||||
|
if (!(orig_args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(args, item->args, sizeof(Item*)*arg_count);
|
memcpy(args, item->args, sizeof(Item*)*arg_count);
|
||||||
|
memcpy(orig_args, item->orig_args, sizeof(Item*)*arg_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -426,12 +440,13 @@ void Item_sum::make_field(Send_field *tmp_field)
|
|||||||
|
|
||||||
void Item_sum::print(String *str)
|
void Item_sum::print(String *str)
|
||||||
{
|
{
|
||||||
|
Item **pargs= orig_args;
|
||||||
str->append(func_name());
|
str->append(func_name());
|
||||||
for (uint i=0 ; i < arg_count ; i++)
|
for (uint i=0 ; i < arg_count ; i++)
|
||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
str->append(',');
|
str->append(',');
|
||||||
args[i]->print(str);
|
pargs[i]->print(str);
|
||||||
}
|
}
|
||||||
str->append(')');
|
str->append(')');
|
||||||
}
|
}
|
||||||
@ -532,6 +547,13 @@ void Item_sum::update_used_tables ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *Item_sum::set_arg(int i, THD *thd, Item *new_val)
|
||||||
|
{
|
||||||
|
thd->change_item_tree(args + i, new_val);
|
||||||
|
return new_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String *
|
String *
|
||||||
Item_sum_num::val_str(String *str)
|
Item_sum_num::val_str(String *str)
|
||||||
{
|
{
|
||||||
@ -583,6 +605,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
|
|||||||
if (check_sum_func(thd, ref))
|
if (check_sum_func(thd, ref))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
memcpy (orig_args, args, sizeof (Item *) * arg_count);
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -670,6 +693,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
|
|||||||
if (check_sum_func(thd, ref))
|
if (check_sum_func(thd, ref))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
orig_args[0]= args[0];
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -3107,6 +3131,12 @@ Item_func_group_concat(Name_resolution_context *context_arg,
|
|||||||
sizeof(ORDER*)*arg_count_order)))
|
sizeof(ORDER*)*arg_count_order)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count)))
|
||||||
|
{
|
||||||
|
args= NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
order= (ORDER**)(args + arg_count);
|
order= (ORDER**)(args + arg_count);
|
||||||
|
|
||||||
/* fill args items of show and sort */
|
/* fill args items of show and sort */
|
||||||
@ -3334,6 +3364,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
|
|||||||
if (check_sum_func(thd, ref))
|
if (check_sum_func(thd, ref))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
memcpy (orig_args, args, sizeof (Item *) * arg_count);
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -228,10 +228,8 @@ public:
|
|||||||
VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC
|
VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC
|
||||||
};
|
};
|
||||||
|
|
||||||
Item **args, *tmp_args[2];
|
|
||||||
Item **ref_by; /* pointer to a ref to the object used to register it */
|
Item **ref_by; /* pointer to a ref to the object used to register it */
|
||||||
Item_sum *next; /* next in the circular chain of registered objects */
|
Item_sum *next; /* next in the circular chain of registered objects */
|
||||||
uint arg_count;
|
|
||||||
Item_sum *in_sum_func; /* embedding set function if any */
|
Item_sum *in_sum_func; /* embedding set function if any */
|
||||||
st_select_lex * aggr_sel; /* select where the function is aggregated */
|
st_select_lex * aggr_sel; /* select where the function is aggregated */
|
||||||
int8 nest_level; /* number of the nesting level of the set function */
|
int8 nest_level; /* number of the nesting level of the set function */
|
||||||
@ -248,24 +246,32 @@ public:
|
|||||||
List<Item_field> outer_fields;
|
List<Item_field> outer_fields;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
uint arg_count;
|
||||||
|
Item **args, *tmp_args[2];
|
||||||
|
/*
|
||||||
|
Copy of the arguments list to hold the original set of arguments.
|
||||||
|
Used in EXPLAIN EXTENDED instead of the current argument list because
|
||||||
|
the current argument list can be altered by usage of temporary tables.
|
||||||
|
*/
|
||||||
|
Item **orig_args, *tmp_orig_args[2];
|
||||||
table_map used_tables_cache;
|
table_map used_tables_cache;
|
||||||
bool forced_const;
|
bool forced_const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void mark_as_sum_func();
|
void mark_as_sum_func();
|
||||||
Item_sum() :arg_count(0), quick_group(1), forced_const(FALSE)
|
Item_sum() :quick_group(1), arg_count(0), forced_const(FALSE)
|
||||||
{
|
{
|
||||||
mark_as_sum_func();
|
mark_as_sum_func();
|
||||||
}
|
}
|
||||||
Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1),
|
Item_sum(Item *a) :quick_group(1), arg_count(1), args(tmp_args),
|
||||||
forced_const(FALSE)
|
orig_args(tmp_orig_args), forced_const(FALSE)
|
||||||
{
|
{
|
||||||
args[0]=a;
|
args[0]=a;
|
||||||
mark_as_sum_func();
|
mark_as_sum_func();
|
||||||
}
|
}
|
||||||
Item_sum( Item *a, Item *b ) :args(tmp_args), arg_count(2), quick_group(1),
|
Item_sum( Item *a, Item *b ) :quick_group(1), arg_count(2), args(tmp_args),
|
||||||
forced_const(FALSE)
|
orig_args(tmp_orig_args), forced_const(FALSE)
|
||||||
{
|
{
|
||||||
args[0]=a; args[1]=b;
|
args[0]=a; args[1]=b;
|
||||||
mark_as_sum_func();
|
mark_as_sum_func();
|
||||||
@ -374,6 +380,10 @@ public:
|
|||||||
bool register_sum_func(THD *thd, Item **ref);
|
bool register_sum_func(THD *thd, Item **ref);
|
||||||
st_select_lex *depended_from()
|
st_select_lex *depended_from()
|
||||||
{ return (nest_level == aggr_level ? 0 : aggr_sel); }
|
{ return (nest_level == aggr_level ? 0 : aggr_sel); }
|
||||||
|
|
||||||
|
Item *get_arg(int i) { return args[i]; }
|
||||||
|
Item *set_arg(int i, THD *thd, Item *new_val);
|
||||||
|
uint get_arg_count() { return arg_count; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -981,6 +991,7 @@ public:
|
|||||||
if (udf.fix_fields(thd, this, this->arg_count, this->args))
|
if (udf.fix_fields(thd, this, this->arg_count, this->args))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
memcpy (orig_args, args, sizeof (Item *) * arg_count);
|
||||||
return check_sum_func(thd, ref);
|
return check_sum_func(thd, ref);
|
||||||
}
|
}
|
||||||
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
|
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
|
||||||
|
@ -1036,12 +1036,25 @@ longlong Item_func_month::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_func_monthname::fix_length_and_dec()
|
||||||
|
{
|
||||||
|
THD* thd= current_thd;
|
||||||
|
CHARSET_INFO *cs= thd->variables.collation_connection;
|
||||||
|
uint32 repertoire= my_charset_repertoire(cs);
|
||||||
|
locale= thd->variables.lc_time_names;
|
||||||
|
collation.set(cs, DERIVATION_COERCIBLE, repertoire);
|
||||||
|
decimals=0;
|
||||||
|
max_length= locale->max_month_name_length * collation.collation->mbmaxlen;
|
||||||
|
maybe_null=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String* Item_func_monthname::val_str(String* str)
|
String* Item_func_monthname::val_str(String* str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
const char *month_name;
|
const char *month_name;
|
||||||
uint month= (uint) val_int();
|
uint month= (uint) val_int();
|
||||||
THD *thd= current_thd;
|
uint err;
|
||||||
|
|
||||||
if (null_value || !month)
|
if (null_value || !month)
|
||||||
{
|
{
|
||||||
@ -1049,8 +1062,9 @@ String* Item_func_monthname::val_str(String* str)
|
|||||||
return (String*) 0;
|
return (String*) 0;
|
||||||
}
|
}
|
||||||
null_value=0;
|
null_value=0;
|
||||||
month_name= thd->variables.lc_time_names->month_names->type_names[month-1];
|
month_name= locale->month_names->type_names[month-1];
|
||||||
str->set(month_name, strlen(month_name), system_charset_info);
|
str->copy(month_name, strlen(month_name), &my_charset_utf8_bin,
|
||||||
|
collation.collation, &err);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1169,19 +1183,32 @@ longlong Item_func_weekday::val_int()
|
|||||||
odbc_type) + test(odbc_type);
|
odbc_type) + test(odbc_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Item_func_dayname::fix_length_and_dec()
|
||||||
|
{
|
||||||
|
THD* thd= current_thd;
|
||||||
|
CHARSET_INFO *cs= thd->variables.collation_connection;
|
||||||
|
uint32 repertoire= my_charset_repertoire(cs);
|
||||||
|
locale= thd->variables.lc_time_names;
|
||||||
|
collation.set(cs, DERIVATION_COERCIBLE, repertoire);
|
||||||
|
decimals=0;
|
||||||
|
max_length= locale->max_day_name_length * collation.collation->mbmaxlen;
|
||||||
|
maybe_null=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String* Item_func_dayname::val_str(String* str)
|
String* Item_func_dayname::val_str(String* str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
uint weekday=(uint) val_int(); // Always Item_func_daynr()
|
uint weekday=(uint) val_int(); // Always Item_func_daynr()
|
||||||
const char *day_name;
|
const char *day_name;
|
||||||
THD *thd= current_thd;
|
uint err;
|
||||||
|
|
||||||
if (null_value)
|
if (null_value)
|
||||||
return (String*) 0;
|
return (String*) 0;
|
||||||
|
|
||||||
day_name= thd->variables.lc_time_names->day_names->type_names[weekday];
|
day_name= locale->day_names->type_names[weekday];
|
||||||
str->set(day_name, strlen(day_name), system_charset_info);
|
str->copy(day_name, strlen(day_name), &my_charset_utf8_bin,
|
||||||
|
collation.collation, &err);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,18 +108,13 @@ public:
|
|||||||
|
|
||||||
class Item_func_monthname :public Item_func_month
|
class Item_func_monthname :public Item_func_month
|
||||||
{
|
{
|
||||||
|
MY_LOCALE *locale;
|
||||||
public:
|
public:
|
||||||
Item_func_monthname(Item *a) :Item_func_month(a) {}
|
Item_func_monthname(Item *a) :Item_func_month(a) {}
|
||||||
const char *func_name() const { return "monthname"; }
|
const char *func_name() const { return "monthname"; }
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
enum Item_result result_type () const { return STRING_RESULT; }
|
enum Item_result result_type () const { return STRING_RESULT; }
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec();
|
||||||
{
|
|
||||||
collation.set(&my_charset_bin);
|
|
||||||
decimals=0;
|
|
||||||
max_length=10*my_charset_bin.mbmaxlen;
|
|
||||||
maybe_null=1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -272,18 +267,13 @@ public:
|
|||||||
|
|
||||||
class Item_func_dayname :public Item_func_weekday
|
class Item_func_dayname :public Item_func_weekday
|
||||||
{
|
{
|
||||||
|
MY_LOCALE *locale;
|
||||||
public:
|
public:
|
||||||
Item_func_dayname(Item *a) :Item_func_weekday(a,0) {}
|
Item_func_dayname(Item *a) :Item_func_weekday(a,0) {}
|
||||||
const char *func_name() const { return "dayname"; }
|
const char *func_name() const { return "dayname"; }
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
enum Item_result result_type () const { return STRING_RESULT; }
|
enum Item_result result_type () const { return STRING_RESULT; }
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec();
|
||||||
{
|
|
||||||
collation.set(&my_charset_bin);
|
|
||||||
decimals=0;
|
|
||||||
max_length=9*MY_CHARSET_BIN_MB_MAXLEN;
|
|
||||||
maybe_null=1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
213
sql/log.cc
213
sql/log.cc
@ -417,6 +417,7 @@ MYSQL_LOG::MYSQL_LOG()
|
|||||||
index_file_name[0] = 0;
|
index_file_name[0] = 0;
|
||||||
bzero((char*) &log_file,sizeof(log_file));
|
bzero((char*) &log_file,sizeof(log_file));
|
||||||
bzero((char*) &index_file, sizeof(index_file));
|
bzero((char*) &index_file, sizeof(index_file));
|
||||||
|
bzero((char*) &purge_temp, sizeof(purge_temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is called only once */
|
/* this is called only once */
|
||||||
@ -1059,10 +1060,10 @@ err:
|
|||||||
|
|
||||||
IMPLEMENTATION
|
IMPLEMENTATION
|
||||||
- Protects index file with LOCK_index
|
- Protects index file with LOCK_index
|
||||||
|
- Read the next file name from the index file and store in rli->linfo
|
||||||
- Delete relevant relay log files
|
- Delete relevant relay log files
|
||||||
- Copy all file names after these ones to the front of the index file
|
- Copy all file names after these ones to the front of the index file
|
||||||
- If the OS has truncate, truncate the file, else fill it with \n'
|
- If the OS has truncate, truncate the file, else fill it with \n'
|
||||||
- Read the next file name from the index file and store in rli->linfo
|
|
||||||
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
0 ok
|
0 ok
|
||||||
@ -1076,6 +1077,7 @@ err:
|
|||||||
int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included)
|
int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
char *to_purge_if_included= NULL;
|
||||||
DBUG_ENTER("purge_first_log");
|
DBUG_ENTER("purge_first_log");
|
||||||
|
|
||||||
DBUG_ASSERT(is_open());
|
DBUG_ASSERT(is_open());
|
||||||
@ -1083,36 +1085,20 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included)
|
|||||||
DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name));
|
DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name));
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_index);
|
pthread_mutex_lock(&LOCK_index);
|
||||||
pthread_mutex_lock(&rli->log_space_lock);
|
to_purge_if_included= my_strdup(rli->group_relay_log_name, MYF(0));
|
||||||
rli->relay_log.purge_logs(rli->group_relay_log_name, included,
|
|
||||||
0, 0, &rli->log_space_total);
|
|
||||||
// Tell the I/O thread to take the relay_log_space_limit into account
|
|
||||||
rli->ignore_log_space_limit= 0;
|
|
||||||
pthread_mutex_unlock(&rli->log_space_lock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Ok to broadcast after the critical region as there is no risk of
|
|
||||||
the mutex being destroyed by this thread later - this helps save
|
|
||||||
context switches
|
|
||||||
*/
|
|
||||||
pthread_cond_broadcast(&rli->log_space_cond);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read the next log file name from the index file and pass it back to
|
Read the next log file name from the index file and pass it back to
|
||||||
the caller
|
the caller.
|
||||||
If included is true, we want the first relay log;
|
|
||||||
otherwise we want the one after event_relay_log_name.
|
|
||||||
*/
|
*/
|
||||||
if ((included && (error=find_log_pos(&rli->linfo, NullS, 0))) ||
|
if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) ||
|
||||||
(!included &&
|
(error=find_next_log(&rli->linfo, 0)))
|
||||||
((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) ||
|
|
||||||
(error=find_next_log(&rli->linfo, 0)))))
|
|
||||||
{
|
{
|
||||||
char buff[22];
|
char buff[22];
|
||||||
sql_print_error("next log error: %d offset: %s log: %s included: %d",
|
sql_print_error("next log error: %d offset: %s log: %s included: %d",
|
||||||
error,
|
error,
|
||||||
llstr(rli->linfo.index_file_offset,buff),
|
llstr(rli->linfo.index_file_offset,buff),
|
||||||
rli->group_relay_log_name,
|
rli->event_relay_log_name,
|
||||||
included);
|
included);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -1140,7 +1126,42 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included)
|
|||||||
/* Store where we are in the new file for the execution thread */
|
/* Store where we are in the new file for the execution thread */
|
||||||
flush_relay_log_info(rli);
|
flush_relay_log_info(rli);
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("crash_before_purge_logs", abort(););
|
||||||
|
|
||||||
|
pthread_mutex_lock(&rli->log_space_lock);
|
||||||
|
rli->relay_log.purge_logs(to_purge_if_included, included,
|
||||||
|
0, 0, &rli->log_space_total);
|
||||||
|
// Tell the I/O thread to take the relay_log_space_limit into account
|
||||||
|
rli->ignore_log_space_limit= 0;
|
||||||
|
pthread_mutex_unlock(&rli->log_space_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ok to broadcast after the critical region as there is no risk of
|
||||||
|
the mutex being destroyed by this thread later - this helps save
|
||||||
|
context switches
|
||||||
|
*/
|
||||||
|
pthread_cond_broadcast(&rli->log_space_cond);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to update the log pos because purge logs has been called
|
||||||
|
* after fetching initially the log pos at the begining of the method.
|
||||||
|
*/
|
||||||
|
if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)))
|
||||||
|
{
|
||||||
|
char buff[22];
|
||||||
|
sql_print_error("next log error: %d offset: %s log: %s included: %d",
|
||||||
|
error,
|
||||||
|
llstr(rli->linfo.index_file_offset,buff),
|
||||||
|
rli->group_relay_log_name,
|
||||||
|
included);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If included was passed, rli->linfo should be the first entry. */
|
||||||
|
DBUG_ASSERT(!included || rli->linfo.index_file_start_offset == 0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
my_free(to_purge_if_included, MYF(0));
|
||||||
pthread_mutex_unlock(&LOCK_index);
|
pthread_mutex_unlock(&LOCK_index);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
@ -1199,8 +1220,36 @@ int MYSQL_LOG::purge_logs(const char *to_log,
|
|||||||
|
|
||||||
if (need_mutex)
|
if (need_mutex)
|
||||||
pthread_mutex_lock(&LOCK_index);
|
pthread_mutex_lock(&LOCK_index);
|
||||||
if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
|
if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
|
||||||
|
{
|
||||||
|
sql_print_error("MYSQL_LOG::purge_logs was called with file %s not "
|
||||||
|
"listed in the index.", to_log);
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
For crash recovery reasons the index needs to be updated before
|
||||||
|
any files are deleted. Move files to be deleted into a temp file
|
||||||
|
to be processed after the index is updated.
|
||||||
|
*/
|
||||||
|
if (!my_b_inited(&purge_temp))
|
||||||
|
{
|
||||||
|
if ((error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX,
|
||||||
|
DISK_BUFFER_SIZE, MYF(MY_WME))))
|
||||||
|
{
|
||||||
|
sql_print_error("MYSQL_LOG::purge_logs failed to open purge_temp");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1)))
|
||||||
|
{
|
||||||
|
sql_print_error("MYSQL_LOG::purge_logs failed to reinit purge_temp "
|
||||||
|
"for write");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
File name exists in index file; delete until we find this file
|
File name exists in index file; delete until we find this file
|
||||||
@ -1211,6 +1260,59 @@ int MYSQL_LOG::purge_logs(const char *to_log,
|
|||||||
while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
|
while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
|
||||||
!log_in_use(log_info.log_file_name))
|
!log_in_use(log_info.log_file_name))
|
||||||
{
|
{
|
||||||
|
if ((error=my_b_write(&purge_temp, (byte*)log_info.log_file_name,
|
||||||
|
strlen(log_info.log_file_name))) ||
|
||||||
|
(error=my_b_write(&purge_temp, (byte*)"\n", 1)))
|
||||||
|
{
|
||||||
|
sql_print_error("MYSQL_LOG::purge_logs failed to copy %s to purge_temp",
|
||||||
|
log_info.log_file_name);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (find_next_log(&log_info, 0) || exit_loop)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We know how many files to delete. Update index file. */
|
||||||
|
if ((error=update_log_index(&log_info, need_update_threads)))
|
||||||
|
{
|
||||||
|
sql_print_error("MSYQL_LOG::purge_logs failed to update the index file");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("crash_after_update_index", abort(););
|
||||||
|
|
||||||
|
/* Switch purge_temp for read. */
|
||||||
|
if ((error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0)))
|
||||||
|
{
|
||||||
|
sql_print_error("MSYQL_LOG::purge_logs failed to reinit purge_temp "
|
||||||
|
"for read");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read each entry from purge_temp and delete the file. */
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
|
||||||
|
if ((length=my_b_gets(&purge_temp, log_info.log_file_name,
|
||||||
|
FN_REFLEN)) <= 1)
|
||||||
|
{
|
||||||
|
if (purge_temp.error)
|
||||||
|
{
|
||||||
|
error= purge_temp.error;
|
||||||
|
sql_print_error("MSYQL_LOG::purge_logs error %d reading from "
|
||||||
|
"purge_temp", error);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reached EOF */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get rid of the trailing '\n' */
|
||||||
|
log_info.log_file_name[length-1]= 0;
|
||||||
|
|
||||||
MY_STAT s;
|
MY_STAT s;
|
||||||
if (!my_stat(log_info.log_file_name, &s, MYF(0)))
|
if (!my_stat(log_info.log_file_name, &s, MYF(0)))
|
||||||
{
|
{
|
||||||
@ -1304,17 +1406,10 @@ int MYSQL_LOG::purge_logs(const char *to_log,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (find_next_log(&log_info, 0) || exit_loop)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
If we get killed -9 here, the sysadmin would have to edit
|
|
||||||
the log index file after restart - otherwise, this should be safe
|
|
||||||
*/
|
|
||||||
error= update_log_index(&log_info, need_update_threads);
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
close_cached_file(&purge_temp);
|
||||||
if (need_mutex)
|
if (need_mutex)
|
||||||
pthread_mutex_unlock(&LOCK_index);
|
pthread_mutex_unlock(&LOCK_index);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
@ -1326,7 +1421,6 @@ err:
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
purge_logs_before_date()
|
purge_logs_before_date()
|
||||||
thd Thread pointer
|
|
||||||
before_date Delete all log files before given date.
|
before_date Delete all log files before given date.
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
@ -1343,6 +1437,7 @@ err:
|
|||||||
int MYSQL_LOG::purge_logs_before_date(time_t purge_time)
|
int MYSQL_LOG::purge_logs_before_date(time_t purge_time)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
char to_log[FN_REFLEN];
|
||||||
LOG_INFO log_info;
|
LOG_INFO log_info;
|
||||||
MY_STAT stat_area;
|
MY_STAT stat_area;
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
@ -1350,12 +1445,8 @@ int MYSQL_LOG::purge_logs_before_date(time_t purge_time)
|
|||||||
DBUG_ENTER("purge_logs_before_date");
|
DBUG_ENTER("purge_logs_before_date");
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_index);
|
pthread_mutex_lock(&LOCK_index);
|
||||||
|
to_log[0]= 0;
|
||||||
|
|
||||||
/*
|
|
||||||
Delete until we find curren file
|
|
||||||
or a file that is used or a file
|
|
||||||
that is older than purge_time.
|
|
||||||
*/
|
|
||||||
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
|
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -1405,54 +1496,18 @@ int MYSQL_LOG::purge_logs_before_date(time_t purge_time)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (stat_area.st_mtime >= purge_time)
|
if (stat_area.st_mtime < purge_time)
|
||||||
|
strmake(to_log,
|
||||||
|
log_info.log_file_name,
|
||||||
|
sizeof(log_info.log_file_name));
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
if (my_delete(log_info.log_file_name, MYF(0)))
|
|
||||||
{
|
|
||||||
if (my_errno == ENOENT)
|
|
||||||
{
|
|
||||||
/* It's not fatal even if we can't delete a log file */
|
|
||||||
if (thd)
|
|
||||||
{
|
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
||||||
ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
|
|
||||||
log_info.log_file_name);
|
|
||||||
}
|
|
||||||
sql_print_information("Failed to delete file '%s'",
|
|
||||||
log_info.log_file_name);
|
|
||||||
my_errno= 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (thd)
|
|
||||||
{
|
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
|
||||||
ER_BINLOG_PURGE_FATAL_ERR,
|
|
||||||
"a problem with deleting %s; "
|
|
||||||
"consider examining correspondence "
|
|
||||||
"of your binlog index file "
|
|
||||||
"to the actual binlog files",
|
|
||||||
log_info.log_file_name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sql_print_information("Failed to delete log file '%s'",
|
|
||||||
log_info.log_file_name);
|
|
||||||
}
|
|
||||||
error= LOG_INFO_FATAL;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (find_next_log(&log_info, 0))
|
if (find_next_log(&log_info, 0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
error= (to_log[0] ? purge_logs(to_log, 1, 0, 1, (ulonglong *) 0) : 0);
|
||||||
If we get killed -9 here, the sysadmin would have to edit
|
|
||||||
the log index file after restart - otherwise, this should be safe
|
|
||||||
*/
|
|
||||||
error= update_log_index(&log_info, 1);
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_index);
|
pthread_mutex_unlock(&LOCK_index);
|
||||||
|
@ -132,15 +132,20 @@ typedef struct my_locale_st
|
|||||||
TYPELIB *ab_month_names;
|
TYPELIB *ab_month_names;
|
||||||
TYPELIB *day_names;
|
TYPELIB *day_names;
|
||||||
TYPELIB *ab_day_names;
|
TYPELIB *ab_day_names;
|
||||||
|
uint max_month_name_length;
|
||||||
|
uint max_day_name_length;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
my_locale_st(uint number_par,
|
my_locale_st(uint number_par,
|
||||||
const char *name_par, const char *descr_par, bool is_ascii_par,
|
const char *name_par, const char *descr_par, bool is_ascii_par,
|
||||||
TYPELIB *month_names_par, TYPELIB *ab_month_names_par,
|
TYPELIB *month_names_par, TYPELIB *ab_month_names_par,
|
||||||
TYPELIB *day_names_par, TYPELIB *ab_day_names_par) :
|
TYPELIB *day_names_par, TYPELIB *ab_day_names_par,
|
||||||
|
uint max_month_name_length_par, uint max_day_name_length_par) :
|
||||||
number(number_par),
|
number(number_par),
|
||||||
name(name_par), description(descr_par), is_ascii(is_ascii_par),
|
name(name_par), description(descr_par), is_ascii(is_ascii_par),
|
||||||
month_names(month_names_par), ab_month_names(ab_month_names_par),
|
month_names(month_names_par), ab_month_names(ab_month_names_par),
|
||||||
day_names(day_names_par), ab_day_names(ab_day_names_par)
|
day_names(day_names_par), ab_day_names(ab_day_names_par),
|
||||||
|
max_month_name_length(max_month_name_length_par),
|
||||||
|
max_day_name_length(max_day_name_length_par)
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
} MY_LOCALE;
|
} MY_LOCALE;
|
||||||
@ -996,6 +1001,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
|
|||||||
bool get_schema_tables_result(JOIN *join,
|
bool get_schema_tables_result(JOIN *join,
|
||||||
enum enum_schema_table_state executed_place);
|
enum enum_schema_table_state executed_place);
|
||||||
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table);
|
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table);
|
||||||
|
bool schema_table_store_record(THD *thd, TABLE *table);
|
||||||
|
|
||||||
bool schema_table_store_record(THD *thd, TABLE *table);
|
bool schema_table_store_record(THD *thd, TABLE *table);
|
||||||
|
|
||||||
|
@ -3617,6 +3617,44 @@ void decrement_handler_count()
|
|||||||
|
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
/*
|
||||||
|
Debugging helper function to keep the locale database
|
||||||
|
(see sql_locale.cc) and max_month_name_length and
|
||||||
|
max_day_name_length variable values in consistent state.
|
||||||
|
*/
|
||||||
|
static void test_lc_time_sz()
|
||||||
|
{
|
||||||
|
DBUG_ENTER("test_lc_time_sz");
|
||||||
|
for (MY_LOCALE **loc= my_locales; *loc; loc++)
|
||||||
|
{
|
||||||
|
uint max_month_len= 0;
|
||||||
|
uint max_day_len = 0;
|
||||||
|
for (const char **month= (*loc)->month_names->type_names; *month; month++)
|
||||||
|
{
|
||||||
|
set_if_bigger(max_month_len,
|
||||||
|
my_numchars_mb(&my_charset_utf8_general_ci,
|
||||||
|
*month, *month + strlen(*month)));
|
||||||
|
}
|
||||||
|
for (const char **day= (*loc)->day_names->type_names; *day; day++)
|
||||||
|
{
|
||||||
|
set_if_bigger(max_day_len,
|
||||||
|
my_numchars_mb(&my_charset_utf8_general_ci,
|
||||||
|
*day, *day + strlen(*day)));
|
||||||
|
}
|
||||||
|
if ((*loc)->max_month_name_length != max_month_len ||
|
||||||
|
(*loc)->max_day_name_length != max_day_len)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("Wrong max day name(or month name) length for locale:",
|
||||||
|
("%s", (*loc)->name));
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
#endif//DBUG_OFF
|
||||||
|
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
int win_main(int argc, char **argv)
|
int win_main(int argc, char **argv)
|
||||||
#else
|
#else
|
||||||
@ -3712,6 +3750,10 @@ int main(int argc, char **argv)
|
|||||||
openlog(libwrapName, LOG_PID, LOG_AUTH);
|
openlog(libwrapName, LOG_PID, LOG_AUTH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
test_lc_time_sz();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We have enough space for fiddling with the argv, continue
|
We have enough space for fiddling with the argv, continue
|
||||||
*/
|
*/
|
||||||
@ -6585,6 +6627,7 @@ struct show_var_st status_vars[]= {
|
|||||||
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
|
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
|
||||||
{"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_CONST},
|
{"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_CONST},
|
||||||
#endif /*HAVE_QUERY_CACHE*/
|
#endif /*HAVE_QUERY_CACHE*/
|
||||||
|
{"Queries", (char*) 0, SHOW_QUERIES},
|
||||||
{"Questions", (char*) offsetof(STATUS_VAR, questions),
|
{"Questions", (char*) offsetof(STATUS_VAR, questions),
|
||||||
SHOW_LONG_STATUS},
|
SHOW_LONG_STATUS},
|
||||||
|
|
||||||
|
@ -1109,6 +1109,9 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
|
|||||||
quick->file= NULL;
|
quick->file= NULL;
|
||||||
quick_selects.delete_elements();
|
quick_selects.delete_elements();
|
||||||
delete pk_quick_select;
|
delete pk_quick_select;
|
||||||
|
/* It's ok to call the next two even if they are already deinitialized */
|
||||||
|
end_read_record(&read_record);
|
||||||
|
free_io_cache(head);
|
||||||
free_root(&alloc,MYF(0));
|
free_root(&alloc,MYF(0));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -7735,7 +7738,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
|
|||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
|
||||||
/* The argument of MIN/MAX. */
|
/* The argument of MIN/MAX. */
|
||||||
Item *expr= min_max_item->args[0]->real_item();
|
Item *expr= min_max_item->get_arg(0)->real_item();
|
||||||
if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */
|
if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */
|
||||||
{
|
{
|
||||||
if (! min_max_arg_item)
|
if (! min_max_arg_item)
|
||||||
|
@ -160,7 +160,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
|||||||
to the number of rows in the tables if this number is exact and
|
to the number of rows in the tables if this number is exact and
|
||||||
there are no outer joins.
|
there are no outer joins.
|
||||||
*/
|
*/
|
||||||
if (!conds && !((Item_sum_count*) item)->args[0]->maybe_null &&
|
if (!conds && !((Item_sum_count*) item)->get_arg(0)->maybe_null &&
|
||||||
!outer_tables && is_exact_count)
|
!outer_tables && is_exact_count)
|
||||||
{
|
{
|
||||||
((Item_sum_count*) item)->make_const(count);
|
((Item_sum_count*) item)->make_const(count);
|
||||||
@ -176,7 +176,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
|||||||
parts of the key is found in the COND, then we can use
|
parts of the key is found in the COND, then we can use
|
||||||
indexes to find the key.
|
indexes to find the key.
|
||||||
*/
|
*/
|
||||||
Item *expr=item_sum->args[0];
|
Item *expr=item_sum->get_arg(0);
|
||||||
if (expr->real_item()->type() == Item::FIELD_ITEM)
|
if (expr->real_item()->type() == Item::FIELD_ITEM)
|
||||||
{
|
{
|
||||||
byte key_buff[MAX_KEY_LENGTH];
|
byte key_buff[MAX_KEY_LENGTH];
|
||||||
@ -319,7 +319,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
|||||||
parts of the key is found in the COND, then we can use
|
parts of the key is found in the COND, then we can use
|
||||||
indexes to find the key.
|
indexes to find the key.
|
||||||
*/
|
*/
|
||||||
Item *expr=item_sum->args[0];
|
Item *expr=item_sum->get_arg(0);
|
||||||
if (expr->real_item()->type() == Item::FIELD_ITEM)
|
if (expr->real_item()->type() == Item::FIELD_ITEM)
|
||||||
{
|
{
|
||||||
byte key_buff[MAX_KEY_LENGTH];
|
byte key_buff[MAX_KEY_LENGTH];
|
||||||
|
@ -3489,6 +3489,7 @@ int set_var_password::check(THD *thd)
|
|||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
if (!user->host.str)
|
if (!user->host.str)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(thd->security_ctx->priv_host);
|
||||||
if (*thd->security_ctx->priv_host != 0)
|
if (*thd->security_ctx->priv_host != 0)
|
||||||
{
|
{
|
||||||
user->host.str= (char *) thd->security_ctx->priv_host;
|
user->host.str= (char *) thd->security_ctx->priv_host;
|
||||||
@ -3500,6 +3501,12 @@ int set_var_password::check(THD *thd)
|
|||||||
user->host.length= 1;
|
user->host.length= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!user->user.str)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(thd->security_ctx->priv_user);
|
||||||
|
user->user.str= (char *) thd->security_ctx->priv_user;
|
||||||
|
user->user.length= strlen(thd->security_ctx->priv_user);
|
||||||
|
}
|
||||||
/* Returns 1 as the function sends error to client */
|
/* Returns 1 as the function sends error to client */
|
||||||
return check_change_password(thd, user->host.str, user->user.str,
|
return check_change_password(thd, user->host.str, user->user.str,
|
||||||
password, strlen(password)) ? 1 : 0;
|
password, strlen(password)) ? 1 : 0;
|
||||||
|
121
sql/sql_acl.cc
121
sql/sql_acl.cc
@ -5953,10 +5953,12 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void update_schema_privilege(TABLE *table, char *buff, const char* db,
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
const char* t_name, const char* column,
|
static bool update_schema_privilege(THD *thd, TABLE *table, char *buff,
|
||||||
uint col_length, const char *priv,
|
const char* db, const char* t_name,
|
||||||
uint priv_length, const char* is_grantable)
|
const char* column, uint col_length,
|
||||||
|
const char *priv, uint priv_length,
|
||||||
|
const char* is_grantable)
|
||||||
{
|
{
|
||||||
int i= 2;
|
int i= 2;
|
||||||
CHARSET_INFO *cs= system_charset_info;
|
CHARSET_INFO *cs= system_charset_info;
|
||||||
@ -5970,13 +5972,15 @@ void update_schema_privilege(TABLE *table, char *buff, const char* db,
|
|||||||
table->field[i++]->store(column, col_length, cs);
|
table->field[i++]->store(column, col_length, cs);
|
||||||
table->field[i++]->store(priv, priv_length, cs);
|
table->field[i++]->store(priv, priv_length, cs);
|
||||||
table->field[i]->store(is_grantable, strlen(is_grantable), cs);
|
table->field[i]->store(is_grantable, strlen(is_grantable), cs);
|
||||||
table->file->write_row(table->record[0]);
|
return schema_table_store_record(thd, table);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||||
{
|
{
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
int error= 0;
|
||||||
uint counter;
|
uint counter;
|
||||||
ACL_USER *acl_user;
|
ACL_USER *acl_user;
|
||||||
ulong want_access;
|
ulong want_access;
|
||||||
@ -6010,8 +6014,14 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
|
|
||||||
strxmov(buff,"'",user,"'@'",host,"'",NullS);
|
strxmov(buff,"'",user,"'@'",host,"'",NullS);
|
||||||
if (!(want_access & ~GRANT_ACL))
|
if (!(want_access & ~GRANT_ACL))
|
||||||
update_schema_privilege(table, buff, 0, 0, 0, 0,
|
{
|
||||||
STRING_WITH_LEN("USAGE"), is_grantable);
|
if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
|
||||||
|
STRING_WITH_LEN("USAGE"), is_grantable))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint priv_id;
|
uint priv_id;
|
||||||
@ -6019,16 +6029,22 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1)
|
for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1)
|
||||||
{
|
{
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
update_schema_privilege(table, buff, 0, 0, 0, 0,
|
{
|
||||||
command_array[priv_id],
|
if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
|
||||||
command_lengths[priv_id], is_grantable);
|
command_array[priv_id],
|
||||||
|
command_lengths[priv_id], is_grantable))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
err:
|
||||||
pthread_mutex_unlock(&acl_cache->lock);
|
pthread_mutex_unlock(&acl_cache->lock);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(error);
|
||||||
#else
|
#else
|
||||||
return(0);
|
return(0);
|
||||||
#endif
|
#endif
|
||||||
@ -6038,6 +6054,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||||
{
|
{
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
int error= 0;
|
||||||
uint counter;
|
uint counter;
|
||||||
ACL_DB *acl_db;
|
ACL_DB *acl_db;
|
||||||
ulong want_access;
|
ulong want_access;
|
||||||
@ -6075,24 +6092,36 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
}
|
}
|
||||||
strxmov(buff,"'",user,"'@'",host,"'",NullS);
|
strxmov(buff,"'",user,"'@'",host,"'",NullS);
|
||||||
if (!(want_access & ~GRANT_ACL))
|
if (!(want_access & ~GRANT_ACL))
|
||||||
update_schema_privilege(table, buff, acl_db->db, 0, 0,
|
{
|
||||||
0, STRING_WITH_LEN("USAGE"), is_grantable);
|
if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0,
|
||||||
|
0, STRING_WITH_LEN("USAGE"), is_grantable))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int cnt;
|
int cnt;
|
||||||
ulong j,test_access= want_access & ~GRANT_ACL;
|
ulong j,test_access= want_access & ~GRANT_ACL;
|
||||||
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
|
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
update_schema_privilege(table, buff, acl_db->db, 0, 0, 0,
|
{
|
||||||
command_array[cnt], command_lengths[cnt],
|
if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, 0,
|
||||||
is_grantable);
|
command_array[cnt], command_lengths[cnt],
|
||||||
|
is_grantable))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
err:
|
||||||
pthread_mutex_unlock(&acl_cache->lock);
|
pthread_mutex_unlock(&acl_cache->lock);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(error);
|
||||||
#else
|
#else
|
||||||
return (0);
|
return (0);
|
||||||
#endif
|
#endif
|
||||||
@ -6102,6 +6131,7 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||||
{
|
{
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
int error= 0;
|
||||||
uint index;
|
uint index;
|
||||||
char buff[100];
|
char buff[100];
|
||||||
TABLE *table= tables->table;
|
TABLE *table= tables->table;
|
||||||
@ -6141,8 +6171,15 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
|
|
||||||
strxmov(buff, "'", user, "'@'", host, "'", NullS);
|
strxmov(buff, "'", user, "'@'", host, "'", NullS);
|
||||||
if (!test_access)
|
if (!test_access)
|
||||||
update_schema_privilege(table, buff, grant_table->db, grant_table->tname,
|
{
|
||||||
0, 0, STRING_WITH_LEN("USAGE"), is_grantable);
|
if (update_schema_privilege(thd, table, buff, grant_table->db,
|
||||||
|
grant_table->tname, 0, 0,
|
||||||
|
STRING_WITH_LEN("USAGE"), is_grantable))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ulong j;
|
ulong j;
|
||||||
@ -6150,17 +6187,24 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1)
|
for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1)
|
||||||
{
|
{
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
update_schema_privilege(table, buff, grant_table->db,
|
{
|
||||||
grant_table->tname, 0, 0, command_array[cnt],
|
if (update_schema_privilege(thd, table, buff, grant_table->db,
|
||||||
command_lengths[cnt], is_grantable);
|
grant_table->tname, 0, 0,
|
||||||
|
command_array[cnt],
|
||||||
|
command_lengths[cnt], is_grantable))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
err:
|
||||||
rw_unlock(&LOCK_grant);
|
rw_unlock(&LOCK_grant);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(error);
|
||||||
#else
|
#else
|
||||||
return (0);
|
return (0);
|
||||||
#endif
|
#endif
|
||||||
@ -6170,6 +6214,7 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||||
{
|
{
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
int error= 0;
|
||||||
uint index;
|
uint index;
|
||||||
char buff[100];
|
char buff[100];
|
||||||
TABLE *table= tables->table;
|
TABLE *table= tables->table;
|
||||||
@ -6219,22 +6264,28 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
||||||
hash_element(&grant_table->hash_columns,col_index);
|
hash_element(&grant_table->hash_columns,col_index);
|
||||||
if ((grant_column->rights & j) && (table_access & j))
|
if ((grant_column->rights & j) && (table_access & j))
|
||||||
update_schema_privilege(table, buff, grant_table->db,
|
{
|
||||||
grant_table->tname,
|
if (update_schema_privilege(thd, table, buff, grant_table->db,
|
||||||
grant_column->column,
|
grant_table->tname,
|
||||||
grant_column->key_length,
|
grant_column->column,
|
||||||
command_array[cnt],
|
grant_column->key_length,
|
||||||
command_lengths[cnt], is_grantable);
|
command_array[cnt],
|
||||||
|
command_lengths[cnt], is_grantable))
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
err:
|
||||||
rw_unlock(&LOCK_grant);
|
rw_unlock(&LOCK_grant);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(error);
|
||||||
#else
|
#else
|
||||||
return (0);
|
return (0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -205,6 +205,13 @@ class MYSQL_LOG: public TC_LOG
|
|||||||
time_t last_time,query_start;
|
time_t last_time,query_start;
|
||||||
IO_CACHE log_file;
|
IO_CACHE log_file;
|
||||||
IO_CACHE index_file;
|
IO_CACHE index_file;
|
||||||
|
/*
|
||||||
|
purge_temp is a temp file used in purge_logs so that the index file
|
||||||
|
can be updated before deleting files from disk, yielding better crash
|
||||||
|
recovery. It is created on demand the first time purge_logs is called
|
||||||
|
and then reused for subsequent calls. It is cleaned up in cleanup().
|
||||||
|
*/
|
||||||
|
IO_CACHE purge_temp;
|
||||||
char *name;
|
char *name;
|
||||||
char time_buff[20],db[NAME_LEN+1];
|
char time_buff[20],db[NAME_LEN+1];
|
||||||
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
|
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
|
||||||
|
@ -85,6 +85,7 @@ class Materialized_cursor: public Server_side_cursor
|
|||||||
List<Item> item_list;
|
List<Item> item_list;
|
||||||
ulong fetch_limit;
|
ulong fetch_limit;
|
||||||
ulong fetch_count;
|
ulong fetch_count;
|
||||||
|
bool is_rnd_inited;
|
||||||
public:
|
public:
|
||||||
Materialized_cursor(select_result *result, TABLE *table);
|
Materialized_cursor(select_result *result, TABLE *table);
|
||||||
|
|
||||||
@ -191,7 +192,11 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
|
|||||||
such command is SHOW VARIABLES or SHOW STATUS.
|
such command is SHOW VARIABLES or SHOW STATUS.
|
||||||
*/
|
*/
|
||||||
if (rc)
|
if (rc)
|
||||||
|
{
|
||||||
|
if (result_materialize->materialized_cursor)
|
||||||
|
delete result_materialize->materialized_cursor;
|
||||||
goto err_open;
|
goto err_open;
|
||||||
|
}
|
||||||
|
|
||||||
if (sensitive_cursor->is_open())
|
if (sensitive_cursor->is_open())
|
||||||
{
|
{
|
||||||
@ -532,7 +537,8 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg,
|
|||||||
:Server_side_cursor(&table_arg->mem_root, result_arg),
|
:Server_side_cursor(&table_arg->mem_root, result_arg),
|
||||||
table(table_arg),
|
table(table_arg),
|
||||||
fetch_limit(0),
|
fetch_limit(0),
|
||||||
fetch_count(0)
|
fetch_count(0),
|
||||||
|
is_rnd_inited(0)
|
||||||
{
|
{
|
||||||
fake_unit.init_query();
|
fake_unit.init_query();
|
||||||
fake_unit.thd= table->in_use;
|
fake_unit.thd= table->in_use;
|
||||||
@ -589,11 +595,12 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
|
|||||||
THD *thd= fake_unit.thd;
|
THD *thd= fake_unit.thd;
|
||||||
int rc;
|
int rc;
|
||||||
Query_arena backup_arena;
|
Query_arena backup_arena;
|
||||||
|
|
||||||
thd->set_n_backup_active_arena(this, &backup_arena);
|
thd->set_n_backup_active_arena(this, &backup_arena);
|
||||||
/* Create a list of fields and start sequential scan */
|
/* Create a list of fields and start sequential scan */
|
||||||
rc= (result->prepare(item_list, &fake_unit) ||
|
rc= result->prepare(item_list, &fake_unit);
|
||||||
table->file->ha_rnd_init(TRUE));
|
if (!rc && !(rc= table->file->ha_rnd_init(TRUE)))
|
||||||
|
is_rnd_inited= 1;
|
||||||
|
|
||||||
thd->restore_active_arena(this, &backup_arena);
|
thd->restore_active_arena(this, &backup_arena);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
{
|
{
|
||||||
@ -673,7 +680,8 @@ void Materialized_cursor::close()
|
|||||||
{
|
{
|
||||||
/* Free item_list items */
|
/* Free item_list items */
|
||||||
free_items();
|
free_items();
|
||||||
(void) table->file->ha_rnd_end();
|
if (is_rnd_inited)
|
||||||
|
(void) table->file->ha_rnd_end();
|
||||||
/*
|
/*
|
||||||
We need to grab table->mem_root to prevent free_tmp_table from freeing:
|
We need to grab table->mem_root to prevent free_tmp_table from freeing:
|
||||||
the cursor object was allocated in this memory.
|
the cursor object was allocated in this memory.
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1610,8 +1610,11 @@ JOIN::exec()
|
|||||||
(zero_result_cause?zero_result_cause:"No tables used"));
|
(zero_result_cause?zero_result_cause:"No tables used"));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result->send_fields(*columns_list,
|
if (result->send_fields(*columns_list,
|
||||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
|
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
|
||||||
|
{
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
We have to test for 'conds' here as the WHERE may not be constant
|
We have to test for 'conds' here as the WHERE may not be constant
|
||||||
even if we don't have any tables for prepared statements or if
|
even if we don't have any tables for prepared statements or if
|
||||||
@ -2498,7 +2501,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||||||
if (s->dependent & table->map)
|
if (s->dependent & table->map)
|
||||||
s->dependent |= table->reginfo.join_tab->dependent;
|
s->dependent |= table->reginfo.join_tab->dependent;
|
||||||
}
|
}
|
||||||
if (s->dependent)
|
if (outer_join & s->table->map)
|
||||||
s->table->maybe_null= 1;
|
s->table->maybe_null= 1;
|
||||||
}
|
}
|
||||||
/* Catch illegal cross references for outer joins */
|
/* Catch illegal cross references for outer joins */
|
||||||
@ -9456,11 +9459,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||||||
}
|
}
|
||||||
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
|
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
|
||||||
{ /* Can't calc group yet */
|
{ /* Can't calc group yet */
|
||||||
((Item_sum*) item)->result_field=0;
|
Item_sum *sum_item= (Item_sum *) item;
|
||||||
for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
|
sum_item->result_field=0;
|
||||||
|
for (i=0 ; i < sum_item->get_arg_count() ; i++)
|
||||||
{
|
{
|
||||||
Item **argp= ((Item_sum*) item)->args + i;
|
Item *arg= sum_item->get_arg(i);
|
||||||
Item *arg= *argp;
|
|
||||||
if (!arg->const_item())
|
if (!arg->const_item())
|
||||||
{
|
{
|
||||||
uint field_index= (uint) (reg_field - table->field);
|
uint field_index= (uint) (reg_field - table->field);
|
||||||
@ -9490,7 +9493,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||||||
string_total_length+= new_field->pack_length();
|
string_total_length+= new_field->pack_length();
|
||||||
}
|
}
|
||||||
thd->mem_root= mem_root_save;
|
thd->mem_root= mem_root_save;
|
||||||
thd->change_item_tree(argp, new Item_field(new_field));
|
arg= sum_item->set_arg(i, thd, new Item_field(new_field));
|
||||||
thd->mem_root= &table->mem_root;
|
thd->mem_root= &table->mem_root;
|
||||||
if (!(new_field->flags & NOT_NULL_FLAG))
|
if (!(new_field->flags & NOT_NULL_FLAG))
|
||||||
{
|
{
|
||||||
@ -9499,7 +9502,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||||||
new_field->maybe_null() is still false, it will be
|
new_field->maybe_null() is still false, it will be
|
||||||
changed below. But we have to setup Item_field correctly
|
changed below. But we have to setup Item_field correctly
|
||||||
*/
|
*/
|
||||||
(*argp)->maybe_null=1;
|
arg->maybe_null=1;
|
||||||
}
|
}
|
||||||
new_field->query_id= thd->query_id;
|
new_field->query_id= thd->query_id;
|
||||||
}
|
}
|
||||||
@ -13245,6 +13248,7 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
|
|||||||
length=0;
|
length=0;
|
||||||
for (i=0 ; i < table_count ; i++)
|
for (i=0 ; i < table_count ; i++)
|
||||||
{
|
{
|
||||||
|
bool have_bit_fields= FALSE;
|
||||||
uint null_fields=0,used_fields;
|
uint null_fields=0,used_fields;
|
||||||
|
|
||||||
Field **f_ptr,*field;
|
Field **f_ptr,*field;
|
||||||
@ -13259,13 +13263,16 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
|
|||||||
length+=field->fill_cache_field(copy);
|
length+=field->fill_cache_field(copy);
|
||||||
if (copy->blob_field)
|
if (copy->blob_field)
|
||||||
(*blob_ptr++)=copy;
|
(*blob_ptr++)=copy;
|
||||||
if (field->maybe_null())
|
if (field->real_maybe_null())
|
||||||
null_fields++;
|
null_fields++;
|
||||||
|
if (field->type() == MYSQL_TYPE_BIT &&
|
||||||
|
((Field_bit*)field)->bit_len)
|
||||||
|
have_bit_fields= TRUE;
|
||||||
copy++;
|
copy++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Copy null bits from table */
|
/* Copy null bits from table */
|
||||||
if (null_fields && tables[i].table->s->null_fields)
|
if (null_fields || have_bit_fields)
|
||||||
{ /* must copy null bits */
|
{ /* must copy null bits */
|
||||||
copy->str=(char*) tables[i].table->null_flags;
|
copy->str=(char*) tables[i].table->null_flags;
|
||||||
copy->length= tables[i].table->s->null_bytes;
|
copy->length= tables[i].table->s->null_bytes;
|
||||||
@ -13930,9 +13937,9 @@ count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
|
|||||||
param->quick_group=0; // UDF SUM function
|
param->quick_group=0; // UDF SUM function
|
||||||
param->sum_func_count++;
|
param->sum_func_count++;
|
||||||
|
|
||||||
for (uint i=0 ; i < sum_item->arg_count ; i++)
|
for (uint i=0 ; i < sum_item->get_arg_count() ; i++)
|
||||||
{
|
{
|
||||||
if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
|
if (sum_item->get_arg(i)->real_item()->type() == Item::FIELD_ITEM)
|
||||||
param->field_count++;
|
param->field_count++;
|
||||||
else
|
else
|
||||||
param->func_count++;
|
param->func_count++;
|
||||||
|
@ -235,7 +235,11 @@ public:
|
|||||||
fetching data from a cursor
|
fetching data from a cursor
|
||||||
*/
|
*/
|
||||||
bool resume_nested_loop;
|
bool resume_nested_loop;
|
||||||
table_map const_table_map,found_const_table_map,outer_join;
|
table_map const_table_map,found_const_table_map;
|
||||||
|
/*
|
||||||
|
Bitmap of all inner tables from outer joins
|
||||||
|
*/
|
||||||
|
table_map outer_join;
|
||||||
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
|
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
|
||||||
/*
|
/*
|
||||||
Used to fetch no more than given amount of rows per one
|
Used to fetch no more than given amount of rows per one
|
||||||
|
@ -798,7 +798,7 @@ static bool get_field_default_value(THD *thd, TABLE *table,
|
|||||||
{
|
{
|
||||||
bool has_default;
|
bool has_default;
|
||||||
bool has_now_default;
|
bool has_now_default;
|
||||||
|
enum enum_field_types field_type= field->type();
|
||||||
/*
|
/*
|
||||||
We are using CURRENT_TIMESTAMP instead of NOW because it is
|
We are using CURRENT_TIMESTAMP instead of NOW because it is
|
||||||
more standard
|
more standard
|
||||||
@ -806,7 +806,7 @@ static bool get_field_default_value(THD *thd, TABLE *table,
|
|||||||
has_now_default= table->timestamp_field == field &&
|
has_now_default= table->timestamp_field == field &&
|
||||||
field->unireg_check != Field::TIMESTAMP_UN_FIELD;
|
field->unireg_check != Field::TIMESTAMP_UN_FIELD;
|
||||||
|
|
||||||
has_default= (field->type() != FIELD_TYPE_BLOB &&
|
has_default= (field_type != FIELD_TYPE_BLOB &&
|
||||||
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
|
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
|
||||||
field->unireg_check != Field::NEXT_NUMBER &&
|
field->unireg_check != Field::NEXT_NUMBER &&
|
||||||
!((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
|
!((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
|
||||||
@ -821,7 +821,19 @@ static bool get_field_default_value(THD *thd, TABLE *table,
|
|||||||
{ // Not null by default
|
{ // Not null by default
|
||||||
char tmp[MAX_FIELD_WIDTH];
|
char tmp[MAX_FIELD_WIDTH];
|
||||||
String type(tmp, sizeof(tmp), field->charset());
|
String type(tmp, sizeof(tmp), field->charset());
|
||||||
field->val_str(&type);
|
if (field_type == MYSQL_TYPE_BIT)
|
||||||
|
{
|
||||||
|
longlong dec= field->val_int();
|
||||||
|
char *ptr= longlong2str(dec, tmp + 2, 2);
|
||||||
|
uint32 length= (uint32) (ptr - tmp);
|
||||||
|
tmp[0]= 'b';
|
||||||
|
tmp[1]= '\'';
|
||||||
|
tmp[length]= '\'';
|
||||||
|
type.length(length + 1);
|
||||||
|
quoted= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
field->val_str(&type);
|
||||||
if (type.length())
|
if (type.length())
|
||||||
{
|
{
|
||||||
String def_val;
|
String def_val;
|
||||||
@ -1525,6 +1537,8 @@ static bool show_status_array(THD *thd, const char *wild,
|
|||||||
case SHOW_FLUSHTIME:
|
case SHOW_FLUSHTIME:
|
||||||
nr= (long) (thd->query_start() - flush_status_time);
|
nr= (long) (thd->query_start() - flush_status_time);
|
||||||
end= int10_to_str(nr, buff, 10);
|
end= int10_to_str(nr, buff, 10);
|
||||||
|
case SHOW_QUERIES:
|
||||||
|
end= int10_to_str((long) thd->query_id, buff, 10);
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
case SHOW_RPL_STATUS:
|
case SHOW_RPL_STATUS:
|
||||||
|
@ -1535,7 +1535,9 @@ static bool prepare_blob_field(THD *thd, create_field *sql_field)
|
|||||||
|
|
||||||
if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
|
if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
|
||||||
{
|
{
|
||||||
if (sql_field->sql_type == FIELD_TYPE_BLOB)
|
if (sql_field->sql_type == FIELD_TYPE_BLOB ||
|
||||||
|
sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
|
||||||
|
sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB)
|
||||||
{
|
{
|
||||||
/* The user has given a length to the blob column */
|
/* The user has given a length to the blob column */
|
||||||
sql_field->sql_type= get_blob_type_from_length(sql_field->length);
|
sql_field->sql_type= get_blob_type_from_length(sql_field->length);
|
||||||
|
@ -170,7 +170,7 @@ enum SHOW_TYPE
|
|||||||
SHOW_UNDEF,
|
SHOW_UNDEF,
|
||||||
SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR,
|
SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR,
|
||||||
SHOW_DOUBLE_STATUS,
|
SHOW_DOUBLE_STATUS,
|
||||||
SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME,
|
SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUERIES,
|
||||||
SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
|
SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
|
||||||
SHOW_VARS,
|
SHOW_VARS,
|
||||||
SHOW_FLUSHTIME,
|
SHOW_FLUSHTIME,
|
||||||
|
@ -143,6 +143,24 @@ bool mysql_create_frm(THD *thd, my_string file_name,
|
|||||||
(create_info->min_rows == 1) && (keys == 0));
|
(create_info->min_rows == 1) && (keys == 0));
|
||||||
int2store(fileinfo+28,key_info_length);
|
int2store(fileinfo+28,key_info_length);
|
||||||
|
|
||||||
|
/*
|
||||||
|
This gives us the byte-position of the character at
|
||||||
|
(character-position, not byte-position) TABLE_COMMENT_MAXLEN.
|
||||||
|
The trick here is that character-positions start at 0, so the last
|
||||||
|
character in a maximum-allowed length string would be at char-pos
|
||||||
|
MAXLEN-1; charpos MAXLEN will be the position of the terminator.
|
||||||
|
Consequently, bytepos(charpos(MAXLEN)) should be equal to
|
||||||
|
comment[length] (which should also be the terminator, or at least
|
||||||
|
the first byte after the payload in the strict sense). If this is
|
||||||
|
not so (bytepos(charpos(MAXLEN)) comes /before/ the end of the
|
||||||
|
string), the string is too long.
|
||||||
|
|
||||||
|
For additional credit, realise that UTF-8 has 1-3 bytes before 6.0,
|
||||||
|
and 1-4 bytes in 6.0 (6.0 also has UTF-32). This means that the
|
||||||
|
inlined COMMENT supposedly does not exceed 60 character plus
|
||||||
|
terminator, vulgo, 181 bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
tmp_len= system_charset_info->cset->charpos(system_charset_info,
|
tmp_len= system_charset_info->cset->charpos(system_charset_info,
|
||||||
create_info->comment.str,
|
create_info->comment.str,
|
||||||
create_info->comment.str +
|
create_info->comment.str +
|
||||||
@ -165,14 +183,6 @@ bool mysql_create_frm(THD *thd, my_string file_name,
|
|||||||
strmake((char*) forminfo+47, create_info->comment.str ?
|
strmake((char*) forminfo+47, create_info->comment.str ?
|
||||||
create_info->comment.str : "", create_info->comment.length);
|
create_info->comment.str : "", create_info->comment.length);
|
||||||
forminfo[46]=(uchar) create_info->comment.length;
|
forminfo[46]=(uchar) create_info->comment.length;
|
||||||
#ifdef EXTRA_DEBUG
|
|
||||||
/*
|
|
||||||
EXTRA_DEBUG causes strmake() to initialize its buffer behind the
|
|
||||||
payload with a magic value to detect wrong buffer-sizes. We
|
|
||||||
explicitly zero that segment again.
|
|
||||||
*/
|
|
||||||
memset((char*) forminfo+47 + forminfo[46], 0, 61 - forminfo[46]);
|
|
||||||
#endif
|
|
||||||
if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) ||
|
if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) ||
|
||||||
my_pwrite(file,(byte*) keybuff,key_info_length,
|
my_pwrite(file,(byte*) keybuff,key_info_length,
|
||||||
(ulong) uint2korr(fileinfo+6),MYF_RW))
|
(ulong) uint2korr(fileinfo+6),MYF_RW))
|
||||||
|
@ -337,6 +337,16 @@ my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns repertoire for charset
|
||||||
|
*/
|
||||||
|
uint my_charset_repertoire(CHARSET_INFO *cs)
|
||||||
|
{
|
||||||
|
return cs->state & MY_CS_PUREASCII ?
|
||||||
|
MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Detect whether a character set is ASCII compatible.
|
Detect whether a character set is ASCII compatible.
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ sort_buffer_size = 64K
|
|||||||
read_buffer_size = 256K
|
read_buffer_size = 256K
|
||||||
read_rnd_buffer_size = 256K
|
read_rnd_buffer_size = 256K
|
||||||
net_buffer_length = 2K
|
net_buffer_length = 2K
|
||||||
thread_stack = 64K
|
thread_stack = 128K
|
||||||
|
|
||||||
# Don't listen on a TCP/IP port at all. This can be a security enhancement,
|
# Don't listen on a TCP/IP port at all. This can be a security enhancement,
|
||||||
# if all processes that need to connect to mysqld run on the same host.
|
# if all processes that need to connect to mysqld run on the same host.
|
||||||
|
@ -15899,6 +15899,61 @@ static void test_bug28934()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_SPATIAL
|
||||||
|
/**
|
||||||
|
Bug#37956 memory leak and / or crash with geometry and prepared statements!
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_bug37956(void)
|
||||||
|
{
|
||||||
|
const char *query="select point(?,?)";
|
||||||
|
MYSQL_STMT *stmt=NULL;
|
||||||
|
ulong val=0;
|
||||||
|
MYSQL_BIND bind_param[2];
|
||||||
|
unsigned char buff[2]= { 134, 211 };
|
||||||
|
DBUG_ENTER("test_bug37956");
|
||||||
|
myheader("test_bug37956");
|
||||||
|
|
||||||
|
stmt= mysql_simple_prepare(mysql, query);
|
||||||
|
check_stmt(stmt);
|
||||||
|
|
||||||
|
val=1;
|
||||||
|
mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void *)&val);
|
||||||
|
val=CURSOR_TYPE_READ_ONLY;
|
||||||
|
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void *)&val);
|
||||||
|
val=0;
|
||||||
|
mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS, (void *)&val);
|
||||||
|
|
||||||
|
memset(bind_param, 0, sizeof(bind_param));
|
||||||
|
bind_param[0].buffer_type=MYSQL_TYPE_TINY;
|
||||||
|
bind_param[0].buffer= (void *)buff;
|
||||||
|
bind_param[0].is_null=NULL;
|
||||||
|
bind_param[0].error=NULL;
|
||||||
|
bind_param[0].is_unsigned=1;
|
||||||
|
bind_param[1].buffer_type=MYSQL_TYPE_TINY;
|
||||||
|
bind_param[1].buffer= (void *)(buff+1);
|
||||||
|
bind_param[1].is_null=NULL;
|
||||||
|
bind_param[1].error=NULL;
|
||||||
|
bind_param[1].is_unsigned=1;
|
||||||
|
|
||||||
|
if (mysql_stmt_bind_param(stmt, bind_param))
|
||||||
|
{
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
DIE_UNLESS(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mysql_stmt_execute(stmt))
|
||||||
|
{
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
/* Should never reach here: execution returns an error. */
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
DIE_UNLESS(0);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bug#27592 (stack overrun when storing datetime value using prepared statements)
|
Bug#27592 (stack overrun when storing datetime value using prepared statements)
|
||||||
*/
|
*/
|
||||||
@ -16595,6 +16650,9 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_bug32265", test_bug32265 },
|
{ "test_bug32265", test_bug32265 },
|
||||||
{ "test_bug38486", test_bug38486 },
|
{ "test_bug38486", test_bug38486 },
|
||||||
{ "test_bug40365", test_bug40365 },
|
{ "test_bug40365", test_bug40365 },
|
||||||
|
#ifdef HAVE_SPATIAL
|
||||||
|
{ "test_bug37956", test_bug37956 },
|
||||||
|
#endif
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user