mirror of
https://github.com/MariaDB/server.git
synced 2025-02-01 19:41:47 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.1-maint
into qualinost.(none):/home/mtaylor/src/mysql-5.1-maint
This commit is contained in:
commit
c58e3bc6f0
12 changed files with 162 additions and 72 deletions
|
@ -76,19 +76,20 @@ typedef void * (__cdecl *pthread_handler)(void *);
|
|||
__int64 i64;
|
||||
};
|
||||
struct timespec {
|
||||
union ft64 start;
|
||||
union ft64 tv;
|
||||
/* The max timeout value in millisecond for pthread_cond_timedwait */
|
||||
long timeout_msec;
|
||||
long max_timeout_msec;
|
||||
};
|
||||
#define set_timespec(ABSTIME,SEC) { \
|
||||
GetSystemTimeAsFileTime(&((ABSTIME).start.ft)); \
|
||||
(ABSTIME).timeout_msec= (long)((SEC)*1000); \
|
||||
GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
|
||||
(ABSTIME).tv.i64+= (__int64)(SEC)*10000000; \
|
||||
(ABSTIME).max_timeout_msec= (long)((SEC)*1000); \
|
||||
}
|
||||
#define set_timespec_nsec(ABSTIME,NSEC) { \
|
||||
GetSystemTimeAsFileTime(&((ABSTIME).start.ft)); \
|
||||
(ABSTIME).timeout_msec= (long)((NSEC)/1000000); \
|
||||
GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
|
||||
(ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
|
||||
(ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
|
||||
}
|
||||
#define get_timespec_sec(ABSTIME) ((((ABSTIME).start.i64 / 10000) + (ABSTIME).timeout_msec ) / 1000)
|
||||
|
||||
void win_pthread_init(void);
|
||||
int win_pthread_setspecific(void *A,void *B,uint length);
|
||||
|
@ -410,9 +411,6 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
|
|||
(ABSTIME).ts_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
|
||||
}
|
||||
#endif /* !set_timespec_nsec */
|
||||
#ifndef get_timespec_sec
|
||||
#define get_timespec_sec(ABSTIME) (ABSTIME).ts_sec
|
||||
#endif /* !get_timespec_sec */
|
||||
#else
|
||||
#ifndef set_timespec
|
||||
#define set_timespec(ABSTIME,SEC) \
|
||||
|
@ -431,9 +429,6 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
|
|||
(ABSTIME).tv_nsec= (long) (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
|
||||
}
|
||||
#endif /* !set_timespec_nsec */
|
||||
#ifndef get_timespec_sec
|
||||
#define get_timespec_sec(ABSTIME) (ABSTIME).tv_sec
|
||||
#endif /* !get_timespec_sec */
|
||||
#endif /* HAVE_TIMESPEC_TS_SEC */
|
||||
|
||||
/* safe_mutex adds checking to mutex for easier debugging */
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#ifndef _typelib_h
|
||||
#define _typelib_h
|
||||
|
||||
#include "my_alloc.h"
|
||||
|
||||
typedef struct st_typelib { /* Different types saved here */
|
||||
unsigned int count; /* How many types */
|
||||
const char *name; /* Name of typelib */
|
||||
|
@ -28,6 +30,7 @@ typedef struct st_typelib { /* Different types saved here */
|
|||
extern int find_type(char *x,TYPELIB *typelib,unsigned int full_name);
|
||||
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
|
||||
extern const char *get_type(TYPELIB *typelib,unsigned int nr);
|
||||
extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
|
||||
|
||||
extern TYPELIB sql_protocol_typelib;
|
||||
|
||||
|
|
|
@ -2160,7 +2160,7 @@ then
|
|||
$MYSQLADMIN --no-defaults --socket=$MASTER_MYSOCK1 -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
|
||||
$MYSQLADMIN --no-defaults --socket=$SLAVE_MYSOCK -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
|
||||
$MYSQLADMIN --no-defaults --host=$hostname --port=$MASTER_MYPORT --protocol=tcp -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
|
||||
$MYSQLADMIN --no-defaults --host=$hostname --protocol=tcp --port=`expr $MASTER_MYPORT+1` -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
|
||||
$MYSQLADMIN --no-defaults --host=$hostname --protocol=tcp --port=`expr $MASTER_MYPORT + 1` -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
|
||||
$MYSQLADMIN --no-defaults --host=$hostname --protocol=tcp --port=$SLAVE_MYPORT -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
|
||||
$MYSQLADMIN --no-defaults --host=$hostname --protocol=tcp --port=`expr $SLAVE_MYPORT + 1` -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
|
||||
sleep_until_file_deleted 0 $MASTER_MYPID
|
||||
|
|
|
@ -5816,4 +5816,20 @@ DROP TABLE bug23760, bug23760_log|
|
|||
DROP PROCEDURE bug23760_update_log|
|
||||
DROP PROCEDURE bug23760_test_row_count|
|
||||
DROP FUNCTION bug23760_rc_test|
|
||||
DROP PROCEDURE IF EXISTS bug24117|
|
||||
DROP TABLE IF EXISTS t3|
|
||||
CREATE TABLE t3(c1 ENUM('abc'))|
|
||||
INSERT INTO t3 VALUES('abc')|
|
||||
CREATE PROCEDURE bug24117()
|
||||
BEGIN
|
||||
DECLARE t3c1 ENUM('abc');
|
||||
DECLARE mycursor CURSOR FOR SELECT c1 FROM t3;
|
||||
OPEN mycursor;
|
||||
FLUSH TABLES;
|
||||
FETCH mycursor INTO t3c1;
|
||||
CLOSE mycursor;
|
||||
END|
|
||||
CALL bug24117()|
|
||||
DROP PROCEDURE bug24117|
|
||||
DROP TABLE t3|
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -114,13 +114,13 @@ drop table t1;
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TEMPORARY TABLE `t1` (
|
||||
`a` int(11) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TEST_DIR/var/log/'
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/log/'
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TEMPORARY TABLE `t1` (
|
||||
`a` int(11) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TEST_DIR/var/log/'
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/log/'
|
||||
create table t1 (a int) engine=myisam select 42 a;
|
||||
select * from t1;
|
||||
a
|
||||
|
|
|
@ -6778,6 +6778,30 @@ DROP PROCEDURE bug23760_update_log|
|
|||
DROP PROCEDURE bug23760_test_row_count|
|
||||
DROP FUNCTION bug23760_rc_test|
|
||||
|
||||
#
|
||||
# BUG#24117: server crash on a FETCH with a cursor on a table which is not in
|
||||
# the table cache
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP PROCEDURE IF EXISTS bug24117|
|
||||
DROP TABLE IF EXISTS t3|
|
||||
--enable_warnings
|
||||
CREATE TABLE t3(c1 ENUM('abc'))|
|
||||
INSERT INTO t3 VALUES('abc')|
|
||||
CREATE PROCEDURE bug24117()
|
||||
BEGIN
|
||||
DECLARE t3c1 ENUM('abc');
|
||||
DECLARE mycursor CURSOR FOR SELECT c1 FROM t3;
|
||||
OPEN mycursor;
|
||||
FLUSH TABLES;
|
||||
FETCH mycursor INTO t3c1;
|
||||
CLOSE mycursor;
|
||||
END|
|
||||
CALL bug24117()|
|
||||
DROP PROCEDURE bug24117|
|
||||
DROP TABLE t3|
|
||||
|
||||
#
|
||||
# NOTE: The delimiter is `|`, and not `;`. It is changed to `;`
|
||||
# at the end of the file!
|
||||
|
|
|
@ -147,20 +147,20 @@ connect (session2,localhost,root,,);
|
|||
|
||||
connection session1;
|
||||
disable_query_log;
|
||||
eval create temporary table t1 (a int) engine=myisam data directory="$MYSQL_TEST_DIR/var/log" select 9 a;
|
||||
eval create temporary table t1 (a int) engine=myisam data directory="$MYSQLTEST_VARDIR/log" select 9 a;
|
||||
enable_query_log;
|
||||
# If running test suite with a non standard tmp dir, the "show create table"
|
||||
# will print "DATA_DIRECTORY=". Use replace_result to mask it out
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
show create table t1;
|
||||
|
||||
connection session2;
|
||||
disable_query_log;
|
||||
eval create temporary table t1 (a int) engine=myisam data directory="$MYSQL_TEST_DIR/var/log" select 99 a;
|
||||
eval create temporary table t1 (a int) engine=myisam data directory="$MYSQLTEST_VARDIR/log" select 99 a;
|
||||
enable_query_log;
|
||||
# If running test suite with a non standard tmp dir, the "show create table"
|
||||
# will print "DATA_DIRECTORY=". Use replace_result to mask it out
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
show create table t1;
|
||||
|
||||
connection default;
|
||||
|
|
|
@ -37,7 +37,7 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
|||
|
||||
int pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
return CloseHandle(cond->semaphore) ? 0 : EINVAL;
|
||||
return CloseHandle(cond->semaphore) ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,6 +51,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
|||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
struct timespec *abstime)
|
||||
{
|
||||
|
@ -61,26 +62,26 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||
GetSystemTimeAsFileTime(&now.ft);
|
||||
|
||||
/*
|
||||
- subtract start time from current time(values are in 100ns units
|
||||
Calculate time left to abstime
|
||||
- subtract start time from current time(values are in 100ns units)
|
||||
- convert to millisec by dividing with 10000
|
||||
- subtract time since start from max timeout
|
||||
*/
|
||||
timeout= abstime->timeout_msec - (long)((now.i64 - abstime->start.i64) / 10000);
|
||||
timeout= (long)((abstime->tv.i64 - now.i64) / 10000);
|
||||
|
||||
/* Don't allow the timeout to be negative */
|
||||
if (timeout < 0)
|
||||
timeout = 0L;
|
||||
timeout= 0L;
|
||||
|
||||
/*
|
||||
Make sure the calucated time does not exceed original timeout
|
||||
Make sure the calucated timeout does not exceed original timeout
|
||||
value which could cause "wait for ever" if system time changes
|
||||
*/
|
||||
if (timeout > abstime->timeout_msec)
|
||||
timeout= abstime->timeout_msec;
|
||||
if (timeout > abstime->max_timeout_msec)
|
||||
timeout= abstime->max_timeout_msec;
|
||||
|
||||
InterlockedIncrement(&cond->waiting);
|
||||
LeaveCriticalSection(mutex);
|
||||
result=WaitForSingleObject(cond->semaphore,timeout);
|
||||
result= WaitForSingleObject(cond->semaphore,timeout);
|
||||
InterlockedDecrement(&cond->waiting);
|
||||
EnterCriticalSection(mutex);
|
||||
|
||||
|
|
|
@ -119,3 +119,54 @@ const char *get_type(TYPELIB *typelib, uint nr)
|
|||
return(typelib->type_names[nr]);
|
||||
return "?";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a copy of a specified TYPELIB structure.
|
||||
|
||||
SYNOPSIS
|
||||
copy_typelib()
|
||||
root pointer to a MEM_ROOT object for allocations
|
||||
from pointer to a source TYPELIB structure
|
||||
|
||||
RETURN
|
||||
pointer to the new TYPELIB structure on successful copy, or
|
||||
NULL otherwise
|
||||
*/
|
||||
|
||||
TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from)
|
||||
{
|
||||
TYPELIB *to;
|
||||
uint i;
|
||||
|
||||
if (!from)
|
||||
return NULL;
|
||||
|
||||
if (!(to= (TYPELIB*) alloc_root(root, sizeof(TYPELIB))))
|
||||
return NULL;
|
||||
|
||||
if (!(to->type_names= (const char **)
|
||||
alloc_root(root, (sizeof(char *) + sizeof(int)) * (from->count + 1))))
|
||||
return NULL;
|
||||
to->type_lengths= (unsigned int *)(to->type_names + from->count + 1);
|
||||
to->count= from->count;
|
||||
if (from->name)
|
||||
{
|
||||
if (!(to->name= strdup_root(root, from->name)))
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
to->name= NULL;
|
||||
|
||||
for (i= 0; i < from->count; i++)
|
||||
{
|
||||
if (!(to->type_names[i]= strmake_root(root, from->type_names[i],
|
||||
from->type_lengths[i])))
|
||||
return NULL;
|
||||
to->type_lengths[i]= from->type_lengths[i];
|
||||
}
|
||||
to->type_names[to->count]= NULL;
|
||||
to->type_lengths[to->count]= 0;
|
||||
|
||||
return to;
|
||||
}
|
||||
|
|
|
@ -693,16 +693,11 @@ static const char *queue_wait_msg= "Waiting for next activation";
|
|||
SYNOPSIS
|
||||
Event_queue::get_top_for_execution_if_time()
|
||||
thd [in] Thread
|
||||
now [in] Current timestamp
|
||||
job_data [out] The object to execute
|
||||
abstime [out] Time to sleep
|
||||
|
||||
RETURN VALUE
|
||||
FALSE No error. If *job_data==NULL then top not elligible for execution.
|
||||
Could be that there is no top. If abstime->tv_sec is set to value
|
||||
greater than zero then use abstime with pthread_cond_timedwait().
|
||||
If abstime->tv_sec is zero then sleep with pthread_cond_wait().
|
||||
abstime->tv_nsec is always zero.
|
||||
Could be that there is no top.
|
||||
TRUE Error
|
||||
|
||||
*/
|
||||
|
@ -712,7 +707,6 @@ Event_queue::get_top_for_execution_if_time(THD *thd, Event_job_data **job_data)
|
|||
{
|
||||
bool ret= FALSE;
|
||||
struct timespec top_time;
|
||||
struct timespec *abstime;
|
||||
Event_queue_element *top= NULL;
|
||||
bool to_free= FALSE;
|
||||
bool to_drop= FALSE;
|
||||
|
@ -724,44 +718,40 @@ Event_queue::get_top_for_execution_if_time(THD *thd, Event_job_data **job_data)
|
|||
{
|
||||
int res;
|
||||
|
||||
thd->end_time();
|
||||
time_t now= thd->query_start();
|
||||
abstime= NULL;
|
||||
|
||||
if (queue.elements)
|
||||
/* Break loop if thd has been killed */
|
||||
if (thd->killed)
|
||||
{
|
||||
top= ((Event_queue_element*) queue_element(&queue, 0));
|
||||
set_timespec(top_time,
|
||||
sec_since_epoch_TIME(&top->execute_at) - now);
|
||||
|
||||
abstime= &top_time;
|
||||
DBUG_PRINT("info", ("thd->killed=%d", thd->killed));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!abstime || get_timespec_sec(*abstime) > now)
|
||||
if (!queue.elements)
|
||||
{
|
||||
const char *msg;
|
||||
if (abstime)
|
||||
{
|
||||
next_activation_at= top->execute_at;
|
||||
msg= queue_wait_msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_zero_time(&next_activation_at, MYSQL_TIMESTAMP_DATETIME);
|
||||
msg= queue_empty_msg;
|
||||
}
|
||||
/* There are no events in the queue */
|
||||
set_zero_time(&next_activation_at, MYSQL_TIMESTAMP_DATETIME);
|
||||
|
||||
cond_wait(thd, abstime, msg, SCHED_FUNC, __LINE__);
|
||||
if (thd->killed)
|
||||
{
|
||||
DBUG_PRINT("info", ("thd->killed=%d", thd->killed));
|
||||
goto end;
|
||||
}
|
||||
/* Wait on condition until signaled. Release LOCK_queue while waiting. */
|
||||
cond_wait(thd, NULL, queue_empty_msg, SCHED_FUNC, __LINE__);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
top= ((Event_queue_element*) queue_element(&queue, 0));
|
||||
|
||||
thd->end_time(); /* Get current time */
|
||||
|
||||
time_t seconds_to_next_event=
|
||||
sec_since_epoch_TIME(&top->execute_at) - thd->query_start();
|
||||
next_activation_at= top->execute_at;
|
||||
if (seconds_to_next_event > 0)
|
||||
{
|
||||
/*
|
||||
The queue could have been emptied. Therefore it's safe to start from
|
||||
the beginning. Moreover, this way we will get also the new top, if
|
||||
the element at the top has been changed.
|
||||
Not yet time for top event, wait on condition with
|
||||
time or until signaled. Release LOCK_queue while waiting.
|
||||
*/
|
||||
set_timespec(top_time, seconds_to_next_event);
|
||||
cond_wait(thd, &top_time, queue_wait_msg, SCHED_FUNC, __LINE__);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -803,7 +793,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd, Event_job_data **job_data)
|
|||
else
|
||||
queue_replaced(&queue);
|
||||
|
||||
dbug_dump_queue(now);
|
||||
dbug_dump_queue(thd->query_start());
|
||||
break;
|
||||
}
|
||||
end:
|
||||
|
@ -816,8 +806,7 @@ end:
|
|||
if (to_free)
|
||||
delete top;
|
||||
|
||||
DBUG_PRINT("info", ("returning %d et_new: 0x%lx get_timespec_sec(abstime): %ld ",
|
||||
ret, (long) *job_data, abstime ? get_timespec_sec(*abstime) : 0));
|
||||
DBUG_PRINT("info", ("returning %d et_new: 0x%lx ", ret, (long) *job_data));
|
||||
|
||||
if (*job_data)
|
||||
DBUG_PRINT("info", ("db: %s name: %s definer=%s", (*job_data)->dbname.str,
|
||||
|
|
10
sql/field.cc
10
sql/field.cc
|
@ -8029,6 +8029,16 @@ void Field_enum::sql_type(String &res) const
|
|||
}
|
||||
|
||||
|
||||
Field *Field_enum::new_field(MEM_ROOT *root, struct st_table *new_table,
|
||||
bool keep_type)
|
||||
{
|
||||
Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
|
||||
if (res)
|
||||
res->typelib= copy_typelib(root, typelib);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
set type.
|
||||
This is a string which can have a collection of different values.
|
||||
|
|
|
@ -1354,6 +1354,7 @@ public:
|
|||
{
|
||||
flags|=ENUM_FLAG;
|
||||
}
|
||||
Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type);
|
||||
enum_field_types type() const { return FIELD_TYPE_STRING; }
|
||||
enum Item_result cmp_type () const { return INT_RESULT; }
|
||||
enum Item_result cast_to_int_type () const { return INT_RESULT; }
|
||||
|
|
Loading…
Add table
Reference in a new issue