Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into bodhi.(none):/opt/local/work/mysql-5.0-runtime mysql-test/r/sp.result: Auto merged mysql-test/t/sp.test: Auto merged sql/sql_parse.cc: Auto merged
This commit is contained in:
commit
7ac3645abd
@ -19,6 +19,9 @@
|
||||
/* We have to do this define before including windows.h to get the AWE API
|
||||
functions */
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#else
|
||||
/* Get NT 4.0 functions */
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
|
@ -116,6 +116,7 @@ struct timespec {
|
||||
|
||||
void win_pthread_init(void);
|
||||
int win_pthread_setspecific(void *A,void *B,uint length);
|
||||
int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
|
||||
int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
|
||||
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
|
||||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
@ -176,7 +177,7 @@ extern int pthread_mutex_destroy (pthread_mutex_t *);
|
||||
#else
|
||||
#define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0)
|
||||
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
|
||||
#define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
|
||||
#define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
|
||||
#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
|
||||
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
|
||||
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
|
||||
@ -574,7 +575,7 @@ typedef struct st_safe_mutex_info_t
|
||||
|
||||
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
|
||||
const char *file, uint line);
|
||||
int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line);
|
||||
int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line);
|
||||
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
|
||||
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
|
||||
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
|
||||
@ -597,12 +598,12 @@ void safe_mutex_end(FILE *file);
|
||||
#undef pthread_cond_timedwait
|
||||
#undef pthread_mutex_trylock
|
||||
#define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__)
|
||||
#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__)
|
||||
#define pthread_mutex_lock(A) safe_mutex_lock((A), FALSE, __FILE__, __LINE__)
|
||||
#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
|
||||
#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
|
||||
#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
|
||||
#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
|
||||
#define pthread_mutex_trylock(A) pthread_mutex_lock(A)
|
||||
#define pthread_mutex_trylock(A) safe_mutex_lock((A), TRUE, __FILE__, __LINE__)
|
||||
#define pthread_mutex_t safe_mutex_t
|
||||
#define safe_mutex_assert_owner(mp) \
|
||||
DBUG_ASSERT((mp)->count > 0 && \
|
||||
|
@ -6389,4 +6389,180 @@ DROP TABLE t1;
|
||||
|
||||
DROP PROCEDURE p1;
|
||||
DROP PROCEDURE p2;
|
||||
|
||||
#
|
||||
# Bug#31035.
|
||||
#
|
||||
|
||||
#
|
||||
# - Prepare.
|
||||
#
|
||||
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP FUNCTION IF EXISTS f2;
|
||||
DROP FUNCTION IF EXISTS f3;
|
||||
DROP FUNCTION IF EXISTS f4;
|
||||
|
||||
#
|
||||
# - Create required objects.
|
||||
#
|
||||
|
||||
CREATE TABLE t1(c1 INT);
|
||||
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
|
||||
CREATE FUNCTION f1()
|
||||
RETURNS INT
|
||||
NOT DETERMINISTIC
|
||||
RETURN 1;
|
||||
|
||||
CREATE FUNCTION f2(p INT)
|
||||
RETURNS INT
|
||||
NOT DETERMINISTIC
|
||||
RETURN 1;
|
||||
|
||||
CREATE FUNCTION f3()
|
||||
RETURNS INT
|
||||
DETERMINISTIC
|
||||
RETURN 1;
|
||||
|
||||
CREATE FUNCTION f4(p INT)
|
||||
RETURNS INT
|
||||
DETERMINISTIC
|
||||
RETURN 1;
|
||||
|
||||
#
|
||||
# - Check.
|
||||
#
|
||||
|
||||
SELECT f1() AS a FROM t1 GROUP BY a;
|
||||
a
|
||||
1
|
||||
|
||||
SELECT f2(@a) AS a FROM t1 GROUP BY a;
|
||||
a
|
||||
1
|
||||
|
||||
SELECT f3() AS a FROM t1 GROUP BY a;
|
||||
a
|
||||
1
|
||||
|
||||
SELECT f4(0) AS a FROM t1 GROUP BY a;
|
||||
a
|
||||
1
|
||||
|
||||
SELECT f4(@a) AS a FROM t1 GROUP BY a;
|
||||
a
|
||||
1
|
||||
|
||||
#
|
||||
# - Cleanup.
|
||||
#
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
DROP FUNCTION f3;
|
||||
DROP FUNCTION f4;
|
||||
|
||||
#
|
||||
# Bug#31191.
|
||||
#
|
||||
|
||||
#
|
||||
# - Prepare.
|
||||
#
|
||||
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
|
||||
#
|
||||
# - Create required objects.
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
barcode INT(8) UNSIGNED ZEROFILL nOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY barcode (barcode)
|
||||
);
|
||||
|
||||
INSERT INTO t1 (id, barcode) VALUES (1, 12345678);
|
||||
INSERT INTO t1 (id, barcode) VALUES (2, 12345679);
|
||||
|
||||
CREATE TABLE test.t2 (
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
barcode BIGINT(11) UNSIGNED ZEROFILL NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
INSERT INTO test.t2 (id, barcode) VALUES (1, 12345106708);
|
||||
INSERT INTO test.t2 (id, barcode) VALUES (2, 12345106709);
|
||||
|
||||
CREATE FUNCTION f1(p INT(8))
|
||||
RETURNS BIGINT(11) UNSIGNED
|
||||
READS SQL DATA
|
||||
RETURN FLOOR(p/1000)*1000000 + 100000 + FLOOR((p MOD 1000)/10)*100 + (p MOD 10);
|
||||
|
||||
#
|
||||
# - Check.
|
||||
#
|
||||
|
||||
SELECT DISTINCT t1.barcode, f1(t1.barcode)
|
||||
FROM t1
|
||||
INNER JOIN t2
|
||||
ON f1(t1.barcode) = t2.barcode
|
||||
WHERE t1.barcode=12345678;
|
||||
barcode f1(t1.barcode)
|
||||
12345678 12345106708
|
||||
|
||||
#
|
||||
# - Cleanup.
|
||||
#
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP FUNCTION f1;
|
||||
|
||||
#
|
||||
# Bug#31226.
|
||||
#
|
||||
|
||||
#
|
||||
# - Prepare.
|
||||
#
|
||||
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
|
||||
#
|
||||
# - Create required objects.
|
||||
#
|
||||
|
||||
CREATE TABLE t1(id INT);
|
||||
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
|
||||
CREATE FUNCTION f1()
|
||||
RETURNS DATETIME
|
||||
NOT DETERMINISTIC NO SQL
|
||||
RETURN NOW();
|
||||
|
||||
#
|
||||
# - Check.
|
||||
#
|
||||
|
||||
SELECT f1() FROM t1 GROUP BY 1;
|
||||
f1()
|
||||
<timestamp>
|
||||
|
||||
#
|
||||
# - Cleanup.
|
||||
#
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
|
||||
End of 5.0 tests
|
||||
|
@ -7387,4 +7387,294 @@ DROP TABLE t1;
|
||||
DROP PROCEDURE p1;
|
||||
DROP PROCEDURE p2;
|
||||
|
||||
###########################################################################
|
||||
|
||||
#
|
||||
# Bug#31035: select from function, group by result crasher.
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # Bug#31035.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Prepare.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP FUNCTION IF EXISTS f2;
|
||||
DROP FUNCTION IF EXISTS f3;
|
||||
DROP FUNCTION IF EXISTS f4;
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Create required objects.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
CREATE TABLE t1(c1 INT);
|
||||
|
||||
--echo
|
||||
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
|
||||
--echo
|
||||
|
||||
CREATE FUNCTION f1()
|
||||
RETURNS INT
|
||||
NOT DETERMINISTIC
|
||||
RETURN 1;
|
||||
|
||||
--echo
|
||||
|
||||
CREATE FUNCTION f2(p INT)
|
||||
RETURNS INT
|
||||
NOT DETERMINISTIC
|
||||
RETURN 1;
|
||||
|
||||
--echo
|
||||
|
||||
CREATE FUNCTION f3()
|
||||
RETURNS INT
|
||||
DETERMINISTIC
|
||||
RETURN 1;
|
||||
|
||||
--echo
|
||||
|
||||
CREATE FUNCTION f4(p INT)
|
||||
RETURNS INT
|
||||
DETERMINISTIC
|
||||
RETURN 1;
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Check.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
# Not deterministic function, no arguments.
|
||||
|
||||
SELECT f1() AS a FROM t1 GROUP BY a;
|
||||
|
||||
--echo
|
||||
|
||||
# Not deterministic function, non-constant argument.
|
||||
|
||||
SELECT f2(@a) AS a FROM t1 GROUP BY a;
|
||||
|
||||
--echo
|
||||
|
||||
# Deterministic function, no arguments.
|
||||
|
||||
SELECT f3() AS a FROM t1 GROUP BY a;
|
||||
|
||||
--echo
|
||||
|
||||
# Deterministic function, constant argument.
|
||||
|
||||
SELECT f4(0) AS a FROM t1 GROUP BY a;
|
||||
|
||||
--echo
|
||||
|
||||
# Deterministic function, non-constant argument.
|
||||
|
||||
SELECT f4(@a) AS a FROM t1 GROUP BY a;
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Cleanup.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
DROP FUNCTION f3;
|
||||
DROP FUNCTION f4;
|
||||
|
||||
--echo
|
||||
|
||||
###########################################################################
|
||||
|
||||
#
|
||||
# Bug#31191: JOIN in combination with stored function crashes the server.
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
|
||||
--echo #
|
||||
--echo # Bug#31191.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Prepare.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Create required objects.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
barcode INT(8) UNSIGNED ZEROFILL nOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY barcode (barcode)
|
||||
);
|
||||
|
||||
--echo
|
||||
|
||||
INSERT INTO t1 (id, barcode) VALUES (1, 12345678);
|
||||
INSERT INTO t1 (id, barcode) VALUES (2, 12345679);
|
||||
|
||||
--echo
|
||||
|
||||
CREATE TABLE test.t2 (
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
barcode BIGINT(11) UNSIGNED ZEROFILL NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
--echo
|
||||
|
||||
INSERT INTO test.t2 (id, barcode) VALUES (1, 12345106708);
|
||||
INSERT INTO test.t2 (id, barcode) VALUES (2, 12345106709);
|
||||
|
||||
--echo
|
||||
|
||||
CREATE FUNCTION f1(p INT(8))
|
||||
RETURNS BIGINT(11) UNSIGNED
|
||||
READS SQL DATA
|
||||
RETURN FLOOR(p/1000)*1000000 + 100000 + FLOOR((p MOD 1000)/10)*100 + (p MOD 10);
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Check.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
SELECT DISTINCT t1.barcode, f1(t1.barcode)
|
||||
FROM t1
|
||||
INNER JOIN t2
|
||||
ON f1(t1.barcode) = t2.barcode
|
||||
WHERE t1.barcode=12345678;
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Cleanup.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP FUNCTION f1;
|
||||
|
||||
--echo
|
||||
|
||||
###########################################################################
|
||||
|
||||
#
|
||||
# Bug#31226: Group by function crashes mysql.
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
|
||||
--echo #
|
||||
--echo # Bug#31226.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Prepare.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Create required objects.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
CREATE TABLE t1(id INT);
|
||||
|
||||
--echo
|
||||
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
|
||||
--echo
|
||||
|
||||
CREATE FUNCTION f1()
|
||||
RETURNS DATETIME
|
||||
NOT DETERMINISTIC NO SQL
|
||||
RETURN NOW();
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Check.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
--replace_column 1 <timestamp>
|
||||
SELECT f1() FROM t1 GROUP BY 1;
|
||||
|
||||
--echo
|
||||
|
||||
--echo #
|
||||
--echo # - Cleanup.
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
|
||||
--echo
|
||||
|
||||
###########################################################################
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -40,6 +40,29 @@ void win_pthread_init(void)
|
||||
pthread_mutex_init(&THR_LOCK_thread,MY_MUTEX_INIT_FAST);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Adapter to @c pthread_mutex_trylock()
|
||||
|
||||
@retval 0 Mutex was acquired
|
||||
@retval EBUSY Mutex was already locked by a thread
|
||||
*/
|
||||
int
|
||||
win_pthread_mutex_trylock(pthread_mutex_t *mutex)
|
||||
{
|
||||
if (TryEnterCriticalSection(mutex))
|
||||
{
|
||||
/* Don't allow recursive lock */
|
||||
if (mutex->RecursionCount > 1){
|
||||
LeaveCriticalSection(mutex);
|
||||
return EBUSY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** We have tried to use '_beginthreadex' instead of '_beginthread' here
|
||||
** but in this case the program leaks about 512 characters for each
|
||||
|
@ -91,7 +91,7 @@ int safe_mutex_init(safe_mutex_t *mp,
|
||||
}
|
||||
|
||||
|
||||
int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
|
||||
int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line)
|
||||
{
|
||||
int error;
|
||||
if (!mp->file)
|
||||
@ -104,15 +104,50 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mp->global);
|
||||
if (mp->count > 0 && pthread_equal(pthread_self(),mp->thread))
|
||||
if (mp->count > 0)
|
||||
{
|
||||
fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d in thread %s\n",
|
||||
file,line,mp->file, mp->line, my_thread_name());
|
||||
fflush(stderr);
|
||||
abort();
|
||||
if (try_lock)
|
||||
{
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
return EBUSY;
|
||||
}
|
||||
else if (pthread_equal(pthread_self(),mp->thread))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"safe_mutex: Trying to lock mutex at %s, line %d, when the"
|
||||
" mutex was already locked at %s, line %d in thread %s\n",
|
||||
file,line,mp->file, mp->line, my_thread_name());
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mp->global);
|
||||
error=pthread_mutex_lock(&mp->mutex);
|
||||
|
||||
/*
|
||||
If we are imitating trylock(), we need to take special
|
||||
precautions.
|
||||
|
||||
- We cannot use pthread_mutex_lock() only since another thread can
|
||||
overtake this thread and take the lock before this thread
|
||||
causing pthread_mutex_trylock() to hang. In this case, we should
|
||||
just return EBUSY. Hence, we use pthread_mutex_trylock() to be
|
||||
able to return immediately.
|
||||
|
||||
- We cannot just use trylock() and continue execution below, since
|
||||
this would generate an error and abort execution if the thread
|
||||
was overtaken and trylock() returned EBUSY . In this case, we
|
||||
instead just return EBUSY, since this is the expected behaviour
|
||||
of trylock().
|
||||
*/
|
||||
if (try_lock)
|
||||
{
|
||||
error= pthread_mutex_trylock(&mp->mutex);
|
||||
if (error == EBUSY)
|
||||
return error;
|
||||
}
|
||||
else
|
||||
error= pthread_mutex_lock(&mp->mutex);
|
||||
|
||||
if (error || (error=pthread_mutex_lock(&mp->global)))
|
||||
{
|
||||
fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %d\n",
|
||||
|
@ -5583,8 +5583,13 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
|
||||
|
||||
#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
|
||||
}
|
||||
|
||||
if (!m_sp->m_chistics->detistic)
|
||||
used_tables_cache |= RAND_TABLE_BIT;
|
||||
{
|
||||
used_tables_cache |= RAND_TABLE_BIT;
|
||||
const_item_cache= FALSE;
|
||||
}
|
||||
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
@ -5592,6 +5597,10 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
|
||||
void Item_func_sp::update_used_tables()
|
||||
{
|
||||
Item_func::update_used_tables();
|
||||
|
||||
if (!m_sp->m_chistics->detistic)
|
||||
used_tables_cache |= RAND_TABLE_BIT;
|
||||
{
|
||||
used_tables_cache |= RAND_TABLE_BIT;
|
||||
const_item_cache= FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -726,7 +726,6 @@ pthread_handler_t handle_bootstrap(void *arg);
|
||||
void end_thread(THD *thd,bool put_in_cache);
|
||||
void flush_thread_cache();
|
||||
bool mysql_execute_command(THD *thd);
|
||||
bool do_command(THD *thd);
|
||||
bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
char* packet, uint packet_length);
|
||||
void log_slow_statement(THD *thd);
|
||||
|
@ -65,11 +65,6 @@
|
||||
static enum enum_ha_read_modes rkey_to_rnext[]=
|
||||
{ RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
|
||||
|
||||
#define HANDLER_TABLES_HACK(thd) { \
|
||||
TABLE *tmp=thd->open_tables; \
|
||||
thd->open_tables=thd->handler_tables; \
|
||||
thd->handler_tables=tmp; }
|
||||
|
||||
static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags);
|
||||
|
||||
|
||||
@ -187,6 +182,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
|
||||
char *db, *name, *alias;
|
||||
uint dblen, namelen, aliaslen, counter;
|
||||
int error;
|
||||
TABLE *backup_open_tables, *backup_handler_tables;
|
||||
DBUG_ENTER("mysql_ha_open");
|
||||
DBUG_PRINT("enter",("'%s'.'%s' as '%s' reopen: %d",
|
||||
tables->db, tables->table_name, tables->alias,
|
||||
@ -215,18 +211,31 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
|
||||
}
|
||||
}
|
||||
|
||||
/* save open_ and handler_ tables state */
|
||||
backup_open_tables= thd->open_tables;
|
||||
backup_handler_tables= thd->handler_tables;
|
||||
|
||||
/* no pre-opened tables */
|
||||
thd->open_tables= NULL;
|
||||
/* to avoid flushes */
|
||||
thd->handler_tables= NULL;
|
||||
|
||||
/*
|
||||
open_tables() will set 'tables->table' if successful.
|
||||
It must be NULL for a real open when calling open_tables().
|
||||
*/
|
||||
DBUG_ASSERT(! tables->table);
|
||||
HANDLER_TABLES_HACK(thd);
|
||||
|
||||
/* for now HANDLER can be used only for real TABLES */
|
||||
tables->required_type= FRMTYPE_TABLE;
|
||||
error= open_tables(thd, &tables, &counter, 0);
|
||||
|
||||
HANDLER_TABLES_HACK(thd);
|
||||
/* restore the state and merge the opened table into handler_tables list */
|
||||
thd->handler_tables= thd->open_tables ?
|
||||
thd->open_tables->next= backup_handler_tables,
|
||||
thd->open_tables : backup_handler_tables;
|
||||
thd->open_tables= backup_open_tables;
|
||||
|
||||
if (error)
|
||||
goto err;
|
||||
|
||||
@ -351,7 +360,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
||||
ha_rows select_limit_cnt, ha_rows offset_limit_cnt)
|
||||
{
|
||||
TABLE_LIST *hash_tables;
|
||||
TABLE *table;
|
||||
TABLE *table, *backup_open_tables, *backup_handler_tables;
|
||||
MYSQL_LOCK *lock;
|
||||
List<Item> list;
|
||||
Protocol *protocol= thd->protocol;
|
||||
@ -361,7 +370,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
||||
uint num_rows;
|
||||
byte *key;
|
||||
uint key_len;
|
||||
bool not_used;
|
||||
bool need_reopen;
|
||||
DBUG_ENTER("mysql_ha_read");
|
||||
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
|
||||
tables->db, tables->table_name, tables->alias));
|
||||
@ -375,6 +384,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
||||
List_iterator<Item> it(list);
|
||||
it++;
|
||||
|
||||
retry:
|
||||
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
|
||||
(byte*) tables->alias,
|
||||
strlen(tables->alias) + 1)))
|
||||
@ -427,9 +437,28 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
||||
}
|
||||
tables->table=table;
|
||||
|
||||
HANDLER_TABLES_HACK(thd);
|
||||
lock= mysql_lock_tables(thd, &tables->table, 1, 0, ¬_used);
|
||||
HANDLER_TABLES_HACK(thd);
|
||||
/* save open_ and handler_ tables state */
|
||||
backup_open_tables= thd->open_tables;
|
||||
backup_handler_tables= thd->handler_tables;
|
||||
|
||||
/* no pre-opened tables */
|
||||
thd->open_tables= NULL;
|
||||
/* to avoid flushes */
|
||||
thd->handler_tables= NULL;
|
||||
|
||||
lock= mysql_lock_tables(thd, &tables->table, 1,
|
||||
MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, &need_reopen);
|
||||
|
||||
/* restore previous context */
|
||||
thd->handler_tables= backup_handler_tables;
|
||||
thd->open_tables= backup_open_tables;
|
||||
|
||||
if (need_reopen)
|
||||
{
|
||||
mysql_ha_close_table(thd, tables);
|
||||
hash_tables->table= NULL;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (!lock)
|
||||
goto err0; // mysql_lock_tables() printed error message already
|
||||
|
@ -93,6 +93,8 @@ const char *xa_state_names[]={
|
||||
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
|
||||
};
|
||||
|
||||
static bool do_command(THD *thd);
|
||||
|
||||
#ifdef __WIN__
|
||||
static void test_signal(int sig_ptr)
|
||||
{
|
||||
@ -1199,23 +1201,28 @@ pthread_handler_t handle_one_connection(void *arg)
|
||||
}
|
||||
if (thd->user_connect)
|
||||
decrease_user_connections(thd->user_connect);
|
||||
|
||||
if (thd->killed ||
|
||||
net->vio && net->error && net->report_error)
|
||||
{
|
||||
statistic_increment(aborted_threads, &LOCK_status);
|
||||
}
|
||||
|
||||
if (net->error && net->vio != 0 && net->report_error)
|
||||
{
|
||||
if (!thd->killed && thd->variables.log_warnings > 1)
|
||||
sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
|
||||
{
|
||||
sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
|
||||
thd->thread_id,(thd->db ? thd->db : "unconnected"),
|
||||
sctx->user ? sctx->user : "unauthenticated",
|
||||
sctx->host_or_ip,
|
||||
(net->last_errno ? ER(net->last_errno) :
|
||||
ER(ER_UNKNOWN_ERROR)));
|
||||
}
|
||||
|
||||
net_send_error(thd, net->last_errno, NullS);
|
||||
statistic_increment(aborted_threads,&LOCK_status);
|
||||
}
|
||||
else if (thd->killed)
|
||||
{
|
||||
statistic_increment(aborted_threads,&LOCK_status);
|
||||
}
|
||||
|
||||
|
||||
end_thread:
|
||||
close_connection(thd, 0, 1);
|
||||
end_thread(thd,1);
|
||||
@ -1550,12 +1557,12 @@ bool do_command(THD *thd)
|
||||
DBUG_PRINT("info",("Got error %d reading command from socket %s",
|
||||
net->error,
|
||||
vio_description(net->vio)));
|
||||
|
||||
/* Check if we can continue without closing the connection */
|
||||
|
||||
if (net->error != 3)
|
||||
{
|
||||
statistic_increment(aborted_threads,&LOCK_status);
|
||||
DBUG_RETURN(TRUE); // We have to close it.
|
||||
}
|
||||
|
||||
net_send_error(thd, net->last_errno, NullS);
|
||||
net->error= 0;
|
||||
DBUG_RETURN(FALSE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user