summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <kostja@bodhi.(none)>2007-10-08 02:05:55 +0400
committerunknown <kostja@bodhi.(none)>2007-10-08 02:05:55 +0400
commit7ac3645abd23b6ceadf43f1f707081716386de6e (patch)
tree483a34a1e9d5f04c9428982cc9defc2b3b36a4e1
parentf4b6234c489c4b8c3242828953b8ae71e5653c59 (diff)
parent017a0fef9c7c42b879c3157dd66316fefd027835 (diff)
downloadmariadb-git-7ac3645abd23b6ceadf43f1f707081716386de6e.tar.gz
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
-rw-r--r--include/config-win.h3
-rw-r--r--include/my_pthread.h9
-rw-r--r--mysql-test/r/sp.result176
-rw-r--r--mysql-test/t/sp.test290
-rw-r--r--mysys/my_winthread.c23
-rw-r--r--mysys/thr_mutex.c49
-rw-r--r--sql/item_func.cc13
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/sql_handler.cc53
-rw-r--r--sql/sql_parse.cc27
10 files changed, 608 insertions, 36 deletions
diff --git a/include/config-win.h b/include/config-win.h
index 279be7aa5e4..f0804a368bc 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -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
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 1cedbbc4fd0..13b7cf93d6f 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -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 && \
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index a9434f2ef0f..b1120a22dfd 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -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
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 9e0ca965b95..465585a693e 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -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
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index 27ccaef4f23..e94369bec32 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -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
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index 425e5fce459..53ee907e0a3 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -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",
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d03d497dfd0..f7103c22581 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -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;
+ }
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 44eb5590a28..24d02ee6948 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -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);
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 9aefa71647e..89090c9fa63 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -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, &not_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
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 084bcfc3c76..0aa9591e95d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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);