Commit 204aa972 authored by pem@mysql.com's avatar pem@mysql.com

Fixed some of the data collection during parsing.

parent 58d3dda3
...@@ -88,7 +88,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex) ...@@ -88,7 +88,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex)
{ {
const char *dstr = (const char*)lex->buf; const char *dstr = (const char*)lex->buf;
m_mylex= lex; m_call_lex= lex;
m_name= new Item_string(name->str, name->length, default_charset_info); m_name= new Item_string(name->str, name->length, default_charset_info);
m_defstr= new Item_string(dstr, lex->end_of_query - lex->buf, m_defstr= new Item_string(dstr, lex->end_of_query - lex->buf,
default_charset_info); default_charset_info);
...@@ -112,7 +112,7 @@ sp_head::execute(THD *thd) ...@@ -112,7 +112,7 @@ sp_head::execute(THD *thd)
{ {
int ret= 0; int ret= 0;
sp_instr *p; sp_instr *p;
sp_pcontext *pctx = m_mylex->spcont; sp_pcontext *pctx = m_call_lex->spcont;
uint csize = pctx->max_framesize(); uint csize = pctx->max_framesize();
uint params = pctx->params(); uint params = pctx->params();
sp_rcontext *octx = thd->spcont; sp_rcontext *octx = thd->spcont;
...@@ -121,7 +121,7 @@ sp_head::execute(THD *thd) ...@@ -121,7 +121,7 @@ sp_head::execute(THD *thd)
if (csize > 0) if (csize > 0)
{ {
uint i; uint i;
List_iterator_fast<Item> li(m_mylex->value_list); List_iterator_fast<Item> li(m_call_lex->value_list);
Item *it = li++; // Skip first one, it's the procedure name Item *it = li++; // Skip first one, it's the procedure name
nctx = new sp_rcontext(csize); nctx = new sp_rcontext(csize);
...@@ -235,27 +235,51 @@ sp_head::restore_lex(THD *thd) ...@@ -235,27 +235,51 @@ sp_head::restore_lex(THD *thd)
// Update some state in the old one first // Update some state in the old one first
m_lex.ptr= thd->lex.ptr; m_lex.ptr= thd->lex.ptr;
m_lex.next_state= thd->lex.next_state; m_lex.next_state= thd->lex.next_state;
// Collect some data from the sub statement lex.
// We reuse some lists in lex instead of adding new ones to this already
// quite large structure.
// CALL puts the proc. name and parameters in value_list, so we might as // Collect some data from the sub statement lex.
// collect called procedures there.
if (thd->lex.sql_command == SQLCOM_CALL) if (thd->lex.sql_command == SQLCOM_CALL)
{ {
// Assuming we will rarely have more than, say, 10 calls to other // We know they are Item_strings (since we put them there ourselves)
// procedures, this is probably fastest. // It would be slightly faster to keep the list sorted, but we need
Item *proc= thd->lex.value_list.head(); // an "insert before" method to do that.
List_iterator_fast<Item> li(m_lex.value_list); Item_string *proc= static_cast<Item_string*>(thd->lex.value_list.head());
Item *it; String *snew= proc->val_str(NULL);
List_iterator_fast<Item_string> li(m_calls);
Item_string *it;
while ((it= li++)) while ((it= li++))
if (proc->eq(it, FALSE)) {
String *sold= it->val_str(NULL);
if (stringcmp(snew, sold) == 0)
break; break;
}
if (! it) if (! it)
m_lex.value_list.push_back(proc); // Got a new one. m_calls.push_back(proc);
}
// Merge used tables
// QQ ...or just open tables in thd->open_tables?
// This is not entirerly clear at the moment, but for now, we collect
// tables here.
for (SELECT_LEX *sl= thd->lex.all_selects_list ;
sl ;
sl= sl->next_select())
{
for (TABLE_LIST *tables= sl->get_table_list() ;
tables ;
tables= tables->next)
{
List_iterator_fast<char *> li(m_tables);
char **tb;
while ((tb= li++))
if (strcasecmp(tables->real_name, *tb) == 0)
break;
if (! tb)
m_tables.push_back(&tables->real_name);
}
} }
// QQ Copy select_lex.table_list.
memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex
} }
......
...@@ -36,6 +36,8 @@ class sp_head : public Sql_alloc ...@@ -36,6 +36,8 @@ class sp_head : public Sql_alloc
public: public:
my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise
List<Item_string> m_calls; // Called procedures.
List<char *> m_tables; // Used tables.
static void *operator new(size_t size) static void *operator new(size_t size)
{ {
...@@ -89,7 +91,7 @@ private: ...@@ -89,7 +91,7 @@ private:
Item_string *m_name; Item_string *m_name;
Item_string *m_defstr; Item_string *m_defstr;
LEX *m_mylex; // My own lex LEX *m_call_lex; // The CALL's own lex
LEX m_lex; // Temp. store for the other lex LEX m_lex; // Temp. store for the other lex
DYNAMIC_ARRAY m_instr; // The "instructions" DYNAMIC_ARRAY m_instr; // The "instructions"
typedef struct typedef struct
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment