1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-02 09:41:40 +03:00

fixed SP processing for mysql_list_fields() command (BUG#6814)

This commit is contained in:
bell@sanja.is.com.ua
2005-02-13 21:47:00 +02:00
parent ea8caabb10
commit 6da6c5be0c
2 changed files with 151 additions and 87 deletions

View File

@@ -1487,6 +1487,106 @@ bool do_command(THD *thd)
}
#endif /* EMBEDDED_LIBRARY */
static void release_local_lock(THD *thd, TABLE_LIST *locked_tables,
bool old_innodb_table_locks)
{
if (locked_tables)
{
#ifdef HAVE_INNOBASE_DB
thd->variables.innodb_table_locks= old_innodb_table_locks;
#endif
if (thd->locked_tables)
sp_unlock_tables(thd);
}
}
static bool process_nested_sp(THD *thd, LEX *lex, TABLE_LIST** locked_tables)
{
DBUG_ENTER("process_nested_sp");
while (1)
{
if (sp_cache_routines(thd, lex, TYPE_ENUM_FUNCTION))
DBUG_RETURN(TRUE);
if (sp_cache_routines(thd, lex, TYPE_ENUM_PROCEDURE))
DBUG_RETURN(TRUE);
if (!thd->locked_tables &&
lex->sql_command != SQLCOM_CREATE_TABLE &&
lex->sql_command != SQLCOM_CREATE_VIEW)
{
MEM_ROOT *thdmemroot= NULL;
sp_merge_routine_tables(thd, lex);
// QQ Preopen tables to find views and triggers.
// This means we open, close and open again, which sucks, but
// right now it's the easiest way to get it to work. A better
// solution will hopefully be found soon...
if (lex->sptabs.records || lex->query_tables)
{
uint procs, funs, tabs;
if (thd->mem_root != thd->current_arena->mem_root)
{
thdmemroot= thd->mem_root;
thd->mem_root= thd->current_arena->mem_root;
}
if (!sp_merge_table_list(thd, &lex->sptabs, lex->query_tables))
DBUG_RETURN(TRUE);
procs= lex->spprocs.records;
funs= lex->spfuns.records;
tabs= lex->sptabs.records;
if (((*locked_tables)= sp_hash_to_table_list(thd, &lex->sptabs)))
{
// We don't want these updated now
uint ctmpdtabs= thd->status_var.created_tmp_disk_tables;
uint ctmptabs= thd->status_var.created_tmp_tables;
uint count;
thd->shortcut_make_view= TRUE;
open_tables(thd, *locked_tables, &count);
thd->shortcut_make_view= FALSE;
close_thread_tables(thd);
thd->status_var.created_tmp_disk_tables= ctmpdtabs;
thd->status_var.created_tmp_tables= ctmptabs;
thd->clear_error();
mysql_reset_errors(thd);
(*locked_tables)= NULL;
}
// A kludge: Decrease all temp. table's query ids to allow a
// second opening.
for (TABLE *table= thd->temporary_tables; table ; table=table->next)
table->query_id-= 1;
if (procs < lex->spprocs.records ||
funs < lex->spfuns.records ||
tabs < lex->sptabs.records)
{
if (thdmemroot)
thd->mem_root= thdmemroot;
continue; // Found more SPs or tabs, try again
}
}
if (lex->sptabs.records &&
(lex->spfuns.records || lex->spprocs.records) &&
sp_merge_table_list(thd, &lex->sptabs, lex->query_tables))
{
if (((*locked_tables)= sp_hash_to_table_list(thd, &lex->sptabs)))
{
#ifdef HAVE_INNOBASE_DB
thd->variables.innodb_table_locks= FALSE;
#endif
sp_open_and_lock_tables(thd, *locked_tables);
}
}
if (thdmemroot)
thd->mem_root= thdmemroot;
}
break;
} // while (1)
DBUG_RETURN(FALSE);
}
/*
Perform one connection-level (COM_XXXX) command.
SYNOPSIS
@@ -1733,8 +1833,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#else
{
char *fields, *pend;
/* Locked closure of all tables */
TABLE_LIST *locked_tables= NULL;
TABLE_LIST table_list;
LEX_STRING conv_name;
/* Saved variable value */
#ifdef HAVE_INNOBASE_DB
my_bool old_innodb_table_locks= thd->variables.innodb_table_locks;
#endif
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
&LOCK_status);
@@ -1778,12 +1885,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->lex->
select_lex.table_list.link_in_list((byte*) &table_list,
(byte**) &table_list.next_local);
thd->lex->query_tables= &table_list;
thd->shortcut_make_view= 0;
process_nested_sp(thd, thd->lex, &locked_tables);
/* switch on VIEW optimisation: do not fill temporary tables */
thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
mysqld_list_fields(thd,&table_list,fields);
thd->lex->unit.cleanup();
thd->cleanup_after_query();
release_local_lock(thd, locked_tables, old_innodb_table_locks);
break;
}
#endif
@@ -2268,85 +2379,8 @@ mysql_execute_command(THD *thd)
lex->sql_command != SQLCOM_LOCK_TABLES &&
lex->sql_command != SQLCOM_UNLOCK_TABLES)
{
while (1)
{
if (sp_cache_routines(thd, lex, TYPE_ENUM_FUNCTION))
DBUG_RETURN(-1);
if (sp_cache_routines(thd, lex, TYPE_ENUM_PROCEDURE))
DBUG_RETURN(-1);
if (!thd->locked_tables &&
lex->sql_command != SQLCOM_CREATE_TABLE &&
lex->sql_command != SQLCOM_CREATE_VIEW)
{
MEM_ROOT *thdmemroot= NULL;
sp_merge_routine_tables(thd, lex);
// QQ Preopen tables to find views and triggers.
// This means we open, close and open again, which sucks, but
// right now it's the easiest way to get it to work. A better
// solution will hopefully be found soon...
if (lex->sptabs.records || lex->query_tables)
{
uint procs, funs, tabs;
if (thd->mem_root != thd->current_arena->mem_root)
{
thdmemroot= thd->mem_root;
thd->mem_root= thd->current_arena->mem_root;
}
if (!sp_merge_table_list(thd, &lex->sptabs, lex->query_tables))
DBUG_RETURN(-1);
procs= lex->spprocs.records;
funs= lex->spfuns.records;
tabs= lex->sptabs.records;
if ((locked_tables= sp_hash_to_table_list(thd, &lex->sptabs)))
{
// We don't want these updated now
uint ctmpdtabs= thd->status_var.created_tmp_disk_tables;
uint ctmptabs= thd->status_var.created_tmp_tables;
uint count;
thd->shortcut_make_view= TRUE;
open_tables(thd, locked_tables, &count);
thd->shortcut_make_view= FALSE;
close_thread_tables(thd);
thd->status_var.created_tmp_disk_tables= ctmpdtabs;
thd->status_var.created_tmp_tables= ctmptabs;
thd->clear_error();
mysql_reset_errors(thd);
locked_tables= NULL;
}
// A kludge: Decrease all temp. table's query ids to allow a
// second opening.
for (TABLE *table= thd->temporary_tables; table ; table=table->next)
table->query_id-= 1;
if (procs < lex->spprocs.records ||
funs < lex->spfuns.records ||
tabs < lex->sptabs.records)
{
if (thdmemroot)
thd->mem_root= thdmemroot;
continue; // Found more SPs or tabs, try again
}
}
if (lex->sptabs.records &&
(lex->spfuns.records || lex->spprocs.records) &&
sp_merge_table_list(thd, &lex->sptabs, lex->query_tables))
{
if ((locked_tables= sp_hash_to_table_list(thd, &lex->sptabs)))
{
#ifdef HAVE_INNOBASE_DB
thd->variables.innodb_table_locks= FALSE;
#endif
sp_open_and_lock_tables(thd, locked_tables);
}
}
if (thdmemroot)
thd->mem_root= thdmemroot;
}
break;
} // while (1)
if (process_nested_sp(thd, lex, &locked_tables))
DBUG_RETURN(TRUE);
}
/*
@@ -4362,14 +4396,7 @@ cleanup:
thd->lock= 0;
}
if (locked_tables)
{
#ifdef HAVE_INNOBASE_DB
thd->variables.innodb_table_locks= old_innodb_table_locks;
#endif
if (thd->locked_tables)
sp_unlock_tables(thd);
}
release_local_lock(thd, locked_tables, old_innodb_table_locks);
DBUG_RETURN(res || thd->net.report_error);
}