Commit 8ea628e8 authored by unknown's avatar unknown

Added collection of called procedures in a list.

Fixed eval bug; now conditions with local variables work in WHILE et al.
Made mysql_install_db.sh create proc table.


scripts/mysql_install_db.sh:
  Added creation of the mysql.proc table.
  Note: The table format will change later, right now it's rather minimalistic,
  just so things can be tested (and the database can easily be recreated when
  I break it :-/ ).
sql/item.h:
  Removed unused method.
sql/sp_head.cc:
  Added collection of called procedures in a list.
  Fixed eval bug; now conditions with local variables work in WHILE et al.
parent 12addfb4
......@@ -306,6 +306,18 @@ then
c_c="$c_c comment='Column privileges';"
fi
if test ! -f $mdata/proc.frm
then
echo "Preparing proc table"
c_p="$c_p CREATE TABLE proc ("
c_p="$c_p name char(64) binary DEFAULT '' NOT NULL,"
c_p="$c_p body blob DEFAULT '' NOT NULL,"
c_p="$c_p PRIMARY KEY (name)"
c_p="$c_p )"
c_p="$c_p comment='Stored Procedures';"
fi
echo "Installing all prepared tables"
if (
cat << END_OF_DATA
......@@ -324,6 +336,7 @@ $i_f
$c_t
$c_c
$c_p
END_OF_DATA
cat fill_func_tables.sql
) | eval "$execdir/mysqld $defaults --bootstrap --skip-grant-tables \
......
......@@ -126,11 +126,6 @@ class Item_splocal : public Item
return m_offset;
}
virtual Item_result result_type() const
{
return this_const_item()->result_type();
}
// Abstract methods inherited from Item. Just defer the call to
// the item in the frame
inline enum Type type() const
......
......@@ -28,10 +28,13 @@
** if nothing else.
*/
static Item *
eval_func_item(Item *it, enum enum_field_types type)
eval_func_item(THD *thd, Item *it, enum enum_field_types type)
{
it= it->this_item();
if (it->fix_fields(thd, 0, NULL))
return it; // Shouldn't happen?
/* QQ How do we do this? Is there some better way? */
switch (type)
{
......@@ -133,7 +136,7 @@ sp_head::execute(THD *thd)
if (pvar->mode == sp_param_out)
nctx->push_item(it->this_item()); // OUT
else
nctx->push_item(eval_func_item(it, pvar->type)); // IN or INOUT
nctx->push_item(eval_func_item(thd, it, pvar->type)); // IN or INOUT
// Note: If it's OUT or INOUT, it must be a variable.
// QQ: Need to handle "global" user/host variables too!!!
if (pvar->mode == sp_param_in)
......@@ -202,7 +205,9 @@ sp_head::reset_lex(THD *thd)
/* And keep the SP stuff too */
thd->lex.sphead = m_lex.sphead;
thd->lex.spcont = m_lex.spcont;
/* QQ Why isn't this reset by lex_start() ??? */
/* Clear all lists. (QQ Why isn't this reset by lex_start()?).
We may be overdoing this, but we know for sure that value_list must
be cleared at least. */
thd->lex.col_list.empty();
thd->lex.ref_list.empty();
thd->lex.drop_list.empty();
......@@ -229,7 +234,28 @@ sp_head::restore_lex(THD *thd)
// Update some state in the old one first
m_lex.ptr= thd->lex.ptr;
m_lex.next_state= thd->lex.next_state;
// QQ Append tables, fields, etc. from the current lex to mine
// 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 called procedures there.
if (thd->lex.sql_command == SQLCOM_CALL)
{
// Assuming we will rarely have more than, say, 10 calls to other
// procedures, this is probably fastest.
Item *proc= thd->lex.value_list.head();
List_iterator_fast<Item> li(m_lex.value_list);
Item *it;
while ((it= li++))
if (proc->eq(it, FALSE))
break;
if (! it)
m_lex.value_list.push_back(proc); // Got a new one.
}
// QQ Copy select_lex.table_list.
memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex
}
......@@ -285,7 +311,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
int
sp_instr_set::execute(THD *thd, uint *nextp)
{
thd->spcont->set_item(m_offset, eval_func_item(m_value, m_type));
thd->spcont->set_item(m_offset, eval_func_item(thd, m_value, m_type));
*nextp = m_ip+1;
return 0;
}
......@@ -296,7 +322,7 @@ sp_instr_set::execute(THD *thd, uint *nextp)
int
sp_instr_jump_if::execute(THD *thd, uint *nextp)
{
Item *it= eval_func_item(m_expr, MYSQL_TYPE_TINY);
Item *it= eval_func_item(thd, m_expr, MYSQL_TYPE_TINY);
if (it->val_int())
*nextp = m_dest;
......@@ -311,7 +337,7 @@ sp_instr_jump_if::execute(THD *thd, uint *nextp)
int
sp_instr_jump_if_not::execute(THD *thd, uint *nextp)
{
Item *it= eval_func_item(m_expr, MYSQL_TYPE_TINY);
Item *it= eval_func_item(thd, m_expr, MYSQL_TYPE_TINY);
if (! it->val_int())
*nextp = m_dest;
......
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