diff options
author | unknown <serg@serg.mylan> | 2004-06-24 19:46:50 +0200 |
---|---|---|
committer | unknown <serg@serg.mylan> | 2004-06-24 19:46:50 +0200 |
commit | ff736789672632d415d7d75d8b0a2e85b7b7eae4 (patch) | |
tree | 99d5fd1b33e2fdbeb208cef9dae2aa9acf28c5ce /sql | |
parent | c6840712f55f9df9951474b0688e221f0f7c7403 (diff) | |
download | mariadb-git-ff736789672632d415d7d75d8b0a2e85b7b7eae4.tar.gz |
bug#4089 - JOIN::join_free calling mysql_unlock w/o index_end() before
sql/ha_myisam.h:
cleanup
mysql-test/r/bdb.result:
bug#4089
mysql-test/t/bdb.test:
bug#4089
sql/opt_range.cc:
be sloppy
sql/sql_select.cc:
JOIN::join_free - pass it down the tree (of selects)
call mysql_unlock_tables only in top-level select
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_myisam.h | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 34 |
3 files changed, 29 insertions, 10 deletions
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 9069b41364d..f4c45e6524b 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -81,7 +81,7 @@ class ha_myisam: public handler int index_first(byte * buf); int index_last(byte * buf); int index_next_same(byte *buf, const byte *key, uint keylen); - int index_end() { ft_handler=NULL; return handler::index_end(); } + int index_end() { ft_handler=NULL; return 0; } int ft_init() { if (!ft_handler) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3a1d441caac..804bb0a413c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -413,7 +413,8 @@ QUICK_SELECT::~QUICK_SELECT() { if (!dont_free) { - file->ha_index_end(); + if (file->inited) + file->ha_index_end(); free_root(&alloc,MYF(0)); } } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7d0c56aed2b..68da87bc210 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3851,6 +3851,8 @@ JOIN::join_free(bool full) JOIN_TAB *tab,*end; DBUG_ENTER("JOIN::join_free"); + full= full || !select_lex->uncacheable; + if (table) { /* @@ -3862,7 +3864,18 @@ JOIN::join_free(bool full) free_io_cache(table[const_tables]); filesort_free_buffers(table[const_tables]); } - if (full || !select_lex->uncacheable) + + for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit(); unit; + unit= unit->next_unit()) + { + JOIN *join; + for (SELECT_LEX *sl= unit->first_select_in_union(); sl; + sl= sl->next_select()) + if ((join= sl->join)) + join->join_free(full); + } + + if (full) { for (tab= join_tab, end= tab+tables; tab != end; tab++) tab->cleanup(); @@ -3872,22 +3885,27 @@ JOIN::join_free(bool full) { for (tab= join_tab, end= tab+tables; tab != end; tab++) { - if (tab->table && tab->table->file->inited == handler::RND) - tab->table->file->ha_rnd_end(); + if (tab->table) + tab->table->file->ha_index_or_rnd_end(); } } } + /* We are not using tables anymore Unlock all tables. We may be in an INSERT .... SELECT statement. */ - if ((full || !select_lex->uncacheable) && - lock && thd->lock && - !(select_options & SELECT_NO_UNLOCK)) + if (full && lock && thd->lock && !(select_options & SELECT_NO_UNLOCK)) { - mysql_unlock_read_tables(thd, lock);// Don't free join->lock - lock=0; + // TODO: unlock tables even if the join isn't top level select in the tree + if (select_lex == (thd->lex->unit.fake_select_lex ? + thd->lex->unit.fake_select_lex : &thd->lex->select_lex)) + { + mysql_unlock_read_tables(thd, lock); // Don't free join->lock + lock=0; + } } + if (full) { group_fields.delete_elements(); |