summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorbell@sanja.is.com.ua <>2004-02-12 18:50:00 +0200
committerbell@sanja.is.com.ua <>2004-02-12 18:50:00 +0200
commitf20b775c63f4faa2a322c9746762ff20ad02805b (patch)
treef18eb5352524df11fca1447c65471c4866ec1f13 /sql
parent6777120d85d4485af85546c09bab85ba6a478b61 (diff)
downloadmariadb-git-f20b775c63f4faa2a322c9746762ff20ad02805b.tar.gz
PS fixed to be compatible with derived tables (BUG#2641)
Diffstat (limited to 'sql')
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/sql_base.cc8
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_prepare.cc68
4 files changed, 58 insertions, 22 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 3e76a32577c..73cc8b9ce03 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -350,6 +350,8 @@ typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
/* sql_parse.cc */
void free_items(Item *item);
void cleanup_items(Item *item);
+class THD;
+void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
#include "sql_class.h"
#include "opt_range.h"
@@ -687,7 +689,6 @@ bool rm_temporary_table(enum db_type base, char *path);
void free_io_cache(TABLE *entry);
void intern_close_table(TABLE *entry);
bool close_thread_table(THD *thd, TABLE **table_ptr);
-void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
void close_temporary_tables(THD *thd);
TABLE_LIST * find_table_in_list(TABLE_LIST *table,
const char *db_name, const char *table_name);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 4c6ca0fde76..3a09a8fbc8e 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1590,6 +1590,14 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter))
DBUG_RETURN(-1); /* purecov: inspected */
fix_tables_pointers(thd->lex->all_selects_list);
+
+ /*
+ open temporary memory pool, which will be closed in
+ mysql_test_select_fields, mysql_test_upd_fields or
+ mysql_test_insert_fields
+ */
+ if (thd->current_statement)
+ thd->ps_setup_prepare_memory();
DBUG_RETURN(mysql_handle_derived(thd->lex));
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 0d75575f6b7..93703acc97b 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -934,6 +934,7 @@ public:
DBUG_ASSERT(current_statement!=0);
cleanup_items(current_statement->free_list);
free_items(free_list);
+ close_thread_tables(this); // to close derived tables
free_root(&mem_root, MYF(0));
set_item_arena(current_statement);
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 34ccb67cda9..9be11b6154c 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -622,7 +622,12 @@ static bool mysql_test_insert_fields(Prepared_statement *stmt,
DBUG_RETURN(1);
#endif
if (open_and_lock_tables(thd, table_list))
- DBUG_RETURN(1);
+ {
+ // this memory pool was opened in open_and_lock_tables
+ thd->ps_setup_free_memory();
+ DBUG_RETURN(1);
+ }
+
table= table_list->table;
if ((values= its++))
@@ -630,12 +635,12 @@ static bool mysql_test_insert_fields(Prepared_statement *stmt,
uint value_count;
ulong counter= 0;
- thd->ps_setup_prepare_memory();
if (check_insert_fields(thd,table,fields,*values,1))
{
thd->ps_setup_free_memory();
DBUG_RETURN(1);
}
+ // this memory pool was opened in open_and_lock_tables
thd->ps_setup_free_memory();
value_count= values->elements;
@@ -653,6 +658,11 @@ static bool mysql_test_insert_fields(Prepared_statement *stmt,
}
}
}
+ else
+ {
+ // this memory pool was opened in open_and_lock_tables
+ thd->ps_setup_free_memory();
+ }
if (send_prep_stmt(stmt, 0))
DBUG_RETURN(1);
DBUG_RETURN(0);
@@ -683,16 +693,21 @@ static bool mysql_test_upd_fields(Prepared_statement *stmt,
DBUG_RETURN(1);
#endif
if (open_and_lock_tables(thd, table_list))
+ {
+ // this memory pool was opened in open_and_lock_tables
+ thd->ps_setup_free_memory();
DBUG_RETURN(1);
+ }
- thd->ps_setup_prepare_memory();
if (setup_tables(table_list, 0) ||
setup_fields(thd, 0, table_list, fields, 1, 0, 0) ||
setup_conds(thd, table_list, &conds) || thd->net.report_error)
{
+ // this memory pool was opened in open_and_lock_tables
thd->ps_setup_free_memory();
DBUG_RETURN(1);
}
+ // this memory pool was opened in open_and_lock_tables
thd->ps_setup_free_memory();
/*
@@ -748,44 +763,50 @@ static bool mysql_test_select_fields(Prepared_statement *stmt,
DBUG_RETURN(1);
if (open_and_lock_tables(thd, tables))
+ {
+ // this memory pool was opened in open_and_lock_tables
+ thd->ps_setup_free_memory();
DBUG_RETURN(1);
+ }
if (lex->describe)
{
if (send_prep_stmt(stmt, 0))
- DBUG_RETURN(1);
+ goto err;
}
else
{
if (!result && !(result= new select_send()))
{
send_error(thd, ER_OUT_OF_RESOURCES);
- DBUG_RETURN(1);
+ goto err;
}
thd->used_tables= 0; // Updated by setup_fields
- thd->ps_setup_prepare_memory();
if (unit->prepare(thd, result, 0))
- {
- unit->cleanup();
- thd->ps_setup_free_memory();
- DBUG_RETURN(1);
- }
-
+ goto err_prep;
+
if (send_prep_stmt(stmt, fields.elements) ||
thd->protocol_simple.send_fields(&fields, 0)
#ifndef EMBEDDED_LIBRARY
|| net_flush(&thd->net)
#endif
)
- {
- DBUG_RETURN(1);
- }
+ goto err_prep;
+
unit->cleanup();
- thd->ps_setup_free_memory();
}
- DBUG_RETURN(0);
+ // this memory pool was opened in open_and_lock_tables
+ thd->ps_setup_free_memory();
+ DBUG_RETURN(0);
+
+err_prep:
+ unit->cleanup();
+err:
+ // this memory pool was opened in open_and_lock_tables
+ thd->ps_setup_free_memory();
+ DBUG_RETURN(1);
}
@@ -1006,7 +1027,6 @@ void mysql_stmt_execute(THD *thd, char *packet)
stmt->query_id= thd->query_id;
thd->stmt_backup.set_statement(thd);
thd->set_statement(stmt);
- thd->current_statement= stmt;
thd->free_list= 0;
/*
@@ -1051,8 +1071,14 @@ void mysql_stmt_execute(THD *thd, char *packet)
tables->table= 0; // safety - nasty init
tables->table_list= 0;
}
-
- sl->master_unit()->unclean();
+
+ {
+ SELECT_LEX_UNIT *unit= sl->master_unit();
+ unit->unclean();
+ unit->types.empty();
+ // for derived tables & PS (which can't be reset bu Item_subquery)
+ unit->reinit_exec_mechanism();
+ }
}
@@ -1082,10 +1108,10 @@ void mysql_stmt_execute(THD *thd, char *packet)
free_items(thd->free_list);
cleanup_items(stmt->free_list);
+ close_thread_tables(thd); // to close derived tables
free_root(&thd->mem_root, MYF(0));
thd->set_statement(&thd->stmt_backup);
end:
- thd->current_statement= 0;
DBUG_VOID_RETURN;
}