summaryrefslogtreecommitdiff
path: root/sql/sql_prepare.cc
diff options
context:
space:
mode:
authorunknown <kostja@bodhi.local>2007-03-07 13:02:14 +0300
committerunknown <kostja@bodhi.local>2007-03-07 13:02:14 +0300
commit676b59cffa5b3019a0fc6179a1aa6d583aad29fb (patch)
treeb2b9f20bb9930dd07a7e5423a01621996d366ab3 /sql/sql_prepare.cc
parent0ac63815ff77c208b1312427cda72b9680d03709 (diff)
parent7f69b747d091ef3ca5c2e31b3befd8dd02fbf790 (diff)
downloadmariadb-git-676b59cffa5b3019a0fc6179a1aa6d583aad29fb.tar.gz
Merge bodhi.local:/opt/local/work/mysql-5.0-26750
into bodhi.local:/opt/local/work/mysql-5.1-runtime mysql-test/r/trigger.result: Auto merged mysql-test/r/view.result: Auto merged mysql-test/t/trigger.test: Auto merged sql/log_event.cc: Auto merged sql/mysqld.cc: Auto merged sql/sp_head.cc: Auto merged sql/sp_head.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_trigger.cc: Auto merged sql/sql_update.cc: Auto merged sql/table.cc: Auto merged sql/table.h: Auto merged sql/sql_class.cc: Manual merge. sql/sql_class.h: Manual merge. sql/sql_parse.cc: Manual merge. sql/sql_prepare.cc: Manual merge. sql/sql_yacc.yy: Manual merge.
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r--sql/sql_prepare.cc52
1 files changed, 32 insertions, 20 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 7de8a9a64ec..ce6072b2a63 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -99,9 +99,12 @@ public:
#endif
};
-/******************************************************************************
- Prepared_statement: a statement that can contain placeholders
-******************************************************************************/
+/****************************************************************************/
+
+/**
+ @class Prepared_statement
+ @brief Prepared_statement: a statement that can contain placeholders
+*/
class Prepared_statement: public Statement
{
@@ -141,6 +144,16 @@ public:
bool execute(String *expanded_query, bool open_cursor);
/* Destroy this statement */
bool deallocate();
+private:
+ /**
+ Store the parsed tree of a prepared statement here.
+ */
+ LEX main_lex;
+ /**
+ The memory root to allocate parsed tree elements (instances of Item,
+ SELECT_LEX and other classes).
+ */
+ MEM_ROOT main_mem_root;
};
@@ -2073,6 +2086,7 @@ void mysql_sql_stmt_prepare(THD *thd)
delete stmt;
DBUG_VOID_RETURN;
}
+
if (thd->stmt_map.insert(thd, stmt))
{
/* The statement is deleted and an error is set if insert fails */
@@ -2667,17 +2681,18 @@ Select_fetch_protocol_prep::send_data(List<Item> &fields)
****************************************************************************/
Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
- :Statement(INITIALIZED, ++thd_arg->statement_id_counter,
- thd_arg->variables.query_alloc_block_size,
- thd_arg->variables.query_prealloc_size),
+ :Statement(&main_lex, &main_mem_root,
+ INITIALIZED, ++thd_arg->statement_id_counter),
thd(thd_arg),
result(thd_arg),
protocol(protocol_arg),
param_array(0),
param_count(0),
last_errno(0),
- flags((uint) IS_IN_USE)
+ flags((uint) IS_IN_USE)
{
+ init_alloc_root(&main_mem_root, thd_arg->variables.query_alloc_block_size,
+ thd_arg->variables.query_prealloc_size);
*last_error= '\0';
}
@@ -2727,6 +2742,7 @@ Prepared_statement::~Prepared_statement()
*/
free_items();
delete lex->result;
+ free_root(&main_mem_root, MYF(0));
DBUG_VOID_RETURN;
}
@@ -2742,6 +2758,7 @@ void Prepared_statement::cleanup_stmt()
DBUG_ENTER("Prepared_statement::cleanup_stmt");
DBUG_PRINT("enter",("stmt: 0x%lx", (long) this));
+ DBUG_ASSERT(lex->sphead == 0);
/* The order is important */
lex->unit.cleanup();
cleanup_items(free_list);
@@ -2827,18 +2844,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
error= MYSQLparse((void *)thd) || thd->is_fatal_error ||
thd->net.report_error || init_param_array(this);
- /*
- The first thing we do after parse error is freeing sp_head to
- ensure that we have restored original memroot.
- */
- if (error && lex->sphead)
- {
- delete lex->sphead;
- lex->sphead= NULL;
- }
-
lex->safe_to_cache_query= FALSE;
-
/*
While doing context analysis of the query (in check_prepared_statement)
we allocate a lot of additional memory: for open tables, JOINs, derived
@@ -2864,12 +2870,18 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (error == 0)
error= check_prepared_statement(this, name.str != 0);
- /* Free sp_head if check_prepared_statement() failed. */
- if (error && lex->sphead)
+ /*
+ Currently CREATE PROCEDURE/TRIGGER/EVENT are prohibited in prepared
+ statements: ensure we have no memory leak here if by someone tries
+ to PREPARE stmt FROM "CREATE PROCEDURE ..."
+ */
+ DBUG_ASSERT(lex->sphead == NULL || error != 0);
+ if (lex->sphead)
{
delete lex->sphead;
lex->sphead= NULL;
}
+
lex_end(lex);
cleanup_stmt();
thd->restore_backup_statement(this, &stmt_backup);