Merge from Tim's 5.0.76-release tree to make 5.0.77 .

This commit is contained in:
Chad MILLER 2009-01-21 13:45:23 -05:00
commit f68ccd024a
79 changed files with 1887 additions and 433 deletions

View File

@ -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"

View File

@ -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) == '*' &&

View File

@ -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)

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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 */
/************************************************************** /**************************************************************

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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);
} }
/************************************************************** /**************************************************************

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 #

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
# #

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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
{ {

View File

@ -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;

View File

@ -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

View File

@ -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);
}; };

View File

@ -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 *);

View File

@ -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;
} }

View File

@ -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; }

View File

@ -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;
} }

View File

@ -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;
}
}; };

View File

@ -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);

View File

@ -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);

View File

@ -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},

View File

@ -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)

View File

@ -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];

View File

@ -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;

View File

@ -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

View File

@ -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];

View File

@ -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

View File

@ -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++;

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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,

View File

@ -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))

View File

@ -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.

View File

@ -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.

View File

@ -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 }
}; };