Commit c58e3bc6 authored by mtaylor@qualinost.(none)'s avatar mtaylor@qualinost.(none)

Merge bk-internal.mysql.com:/home/bk/mysql-5.1-maint

into  qualinost.(none):/home/mtaylor/src/mysql-5.1-maint
parents d194a83b c4dd2677
......@@ -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;
/* Break loop if thd has been killed */
if (thd->killed)
{
DBUG_PRINT("info", ("thd->killed=%d", thd->killed));
goto end;
}
if (queue.elements)
if (!queue.elements)
{
top= ((Event_queue_element*) queue_element(&queue, 0));
set_timespec(top_time,
sec_since_epoch_TIME(&top->execute_at) - now);
/* There are no events in the queue */
set_zero_time(&next_activation_at, MYSQL_TIMESTAMP_DATETIME);
/* Wait on condition until signaled. Release LOCK_queue while waiting. */
cond_wait(thd, NULL, queue_empty_msg, SCHED_FUNC, __LINE__);
abstime= &top_time;
continue;
}
if (!abstime || get_timespec_sec(*abstime) > now)
{
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;
}
top= ((Event_queue_element*) queue_element(&queue, 0));
cond_wait(thd, abstime, msg, SCHED_FUNC, __LINE__);
if (thd->killed)
{
DBUG_PRINT("info", ("thd->killed=%d", thd->killed));
goto end;
}
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 @@ Event_queue::get_top_for_execution_if_time(THD *thd, Event_job_data **job_data)
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,
......
......@@ -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 @@ class Field_enum :public Field_str {
{
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; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment