summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2002-12-13 18:25:36 +0100
committerunknown <pem@mysql.com>2002-12-13 18:25:36 +0100
commit390b3e745c05a39704c01365958710189e216f79 (patch)
tree9f76b149122a3fe6fcfd6b48d2b395e79cc6910f
parentb1b62274856c81a5f1f7a49384fc93810fd2a2bd (diff)
downloadmariadb-git-390b3e745c05a39704c01365958710189e216f79.tar.gz
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.
-rw-r--r--scripts/mysql_install_db.sh13
-rw-r--r--sql/item.h5
-rw-r--r--sql/sp_head.cc40
3 files changed, 46 insertions, 12 deletions
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 5e139dc652b..6029ac2518a 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -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 \
diff --git a/sql/item.h b/sql/item.h
index 366eb8f2e32..bffb9212e3d 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -126,11 +126,6 @@ public:
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
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 8025fe3ef4c..a2a40d08ecb 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -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;