mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Merging 4.1->5.0.
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union BitKeeper/triggers/post-commit: Auto merged client/mysql.cc: Auto merged configure.in: Auto merged include/my_global.h: Auto merged include/my_pthread.h: Auto merged include/mysql_com.h: Auto merged libmysql/libmysql.c: Auto merged libmysqld/Makefile.am: Auto merged libmysqld/lib_sql.cc: Auto merged myisam/mi_check.c: Auto merged myisam/myisamchk.c: Auto merged myisam/myisamdef.h: Auto merged mysql-test/r/rpl_temporary.result: Auto merged mysql-test/r/show_check.result: Auto merged mysql-test/r/subselect.result: Auto merged mysql-test/r/variables.result: Auto merged mysql-test/t/subselect.test: Auto merged mysql-test/t/variables.test: Auto merged scripts/mysql_install_db.sh: Auto merged sql/Makefile.am: Auto merged sql/ha_berkeley.cc: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_myisam.cc: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item_subselect.cc: Auto merged sql/item_sum.cc: Auto merged sql/item_sum.h: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/slave.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_db.cc: Auto merged sql/sql_delete.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_repl.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_union.cc: Auto merged sql/sql_update.cc: Auto merged sql/table.h: Auto merged
This commit is contained in:
442
sql/sql_parse.cc
442
sql/sql_parse.cc
@@ -26,6 +26,9 @@
|
||||
#include "ha_innodb.h"
|
||||
#endif
|
||||
|
||||
#include "sp_head.h"
|
||||
#include "sp.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
/*
|
||||
Without SSL the handshake consists of one packet. This packet
|
||||
@@ -44,6 +47,15 @@
|
||||
#define MIN_HANDSHAKE_SIZE 6
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
/* Used in error handling only */
|
||||
#define SP_TYPE_STRING(LP) \
|
||||
((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE")
|
||||
#define SP_COM_STRING(LP) \
|
||||
((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
|
||||
(LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
|
||||
(LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
|
||||
"FUNCTION" : "PROCEDURE")
|
||||
|
||||
#ifdef SOLARIS
|
||||
extern "C" int gethostname(char *name, int namelen);
|
||||
#endif
|
||||
@@ -938,7 +950,7 @@ pthread_handler_decl(handle_one_connection,arg)
|
||||
thd->version=refresh_version;
|
||||
thd->set_time();
|
||||
thd->init_for_queries();
|
||||
while (!net->error && net->vio != 0 && !thd->killed)
|
||||
while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION))
|
||||
{
|
||||
if (do_command(thd))
|
||||
break;
|
||||
@@ -1143,7 +1155,7 @@ bool do_command(THD *thd)
|
||||
indicator of uninitialized lex => normal flow of errors handling
|
||||
(see my_message_sql)
|
||||
*/
|
||||
thd->lex.current_select= 0;
|
||||
thd->lex->current_select= 0;
|
||||
|
||||
packet=0;
|
||||
old_timeout=net->read_timeout;
|
||||
@@ -1169,6 +1181,9 @@ bool do_command(THD *thd)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thd->killed == THD::KILL_QUERY)
|
||||
thd->killed= THD::NOT_KILLED;
|
||||
|
||||
packet=(char*) net->read_pos;
|
||||
command = (enum enum_server_command) (uchar) packet[0];
|
||||
if (command >= COM_END)
|
||||
@@ -1204,7 +1219,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
thread_running++;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
|
||||
thd->lex.select_lex.options=0; // We store status here
|
||||
thd->lex->select_lex.options=0; // We store status here
|
||||
switch (command) {
|
||||
case COM_INIT_DB:
|
||||
{
|
||||
@@ -1349,16 +1364,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
DBUG_PRINT("query",("%-.4096s",thd->query));
|
||||
mysql_parse(thd,thd->query, thd->query_length);
|
||||
|
||||
while (!thd->killed && !thd->is_fatal_error && thd->lex.found_colon)
|
||||
while (!thd->killed && !thd->is_fatal_error && thd->lex->found_colon)
|
||||
{
|
||||
char *packet= thd->lex.found_colon;
|
||||
char *packet= thd->lex->found_colon;
|
||||
/*
|
||||
Multiple queries exits, execute them individually
|
||||
*/
|
||||
if (thd->lock || thd->open_tables || thd->derived_tables)
|
||||
close_thread_tables(thd);
|
||||
|
||||
ulong length= thd->query_length-(ulong)(thd->lex.found_colon-thd->query);
|
||||
ulong length= thd->query_length-(ulong)(thd->lex->found_colon-thd->query);
|
||||
|
||||
/* Remove garbage at start of query */
|
||||
while (my_isspace(thd->charset(), *packet) && length > 0)
|
||||
@@ -1580,7 +1595,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
{
|
||||
statistic_increment(com_stat[SQLCOM_KILL],&LOCK_status);
|
||||
ulong id=(ulong) uint4korr(packet);
|
||||
kill_one_thread(thd,id);
|
||||
kill_one_thread(thd,id,false);
|
||||
break;
|
||||
}
|
||||
case COM_SET_OPTION:
|
||||
@@ -1636,7 +1651,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
|
||||
if ((ulong) (thd->start_time - thd->time_after_lock) >
|
||||
thd->variables.long_query_time ||
|
||||
((thd->lex.select_lex.options &
|
||||
((thd->lex->select_lex.options &
|
||||
(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED)) &&
|
||||
(specialflag & SPECIAL_LOG_QUERIES_NOT_USING_INDEXES)))
|
||||
{
|
||||
@@ -1652,6 +1667,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
thread_running--;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
|
||||
|
||||
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
@@ -1707,16 +1723,23 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length)
|
||||
** Execute command saved in thd and current_lex->sql_command
|
||||
****************************************************************************/
|
||||
|
||||
void
|
||||
int
|
||||
mysql_execute_command(THD *thd)
|
||||
{
|
||||
int res= 0;
|
||||
LEX *lex= &thd->lex;
|
||||
LEX *lex= thd->lex;
|
||||
TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first;
|
||||
SELECT_LEX *select_lex= &lex->select_lex;
|
||||
SELECT_LEX_UNIT *unit= &lex->unit;
|
||||
DBUG_ENTER("mysql_execute_command");
|
||||
|
||||
if (lex->sql_command != SQLCOM_CREATE_PROCEDURE &&
|
||||
lex->sql_command != SQLCOM_CREATE_SPFUNCTION)
|
||||
{
|
||||
if (sp_cache_functions(thd, lex))
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
Reset warning count for each query that uses tables
|
||||
A better approach would be to reset this for any commands
|
||||
@@ -1737,7 +1760,7 @@ mysql_execute_command(THD *thd)
|
||||
{
|
||||
/* we warn the slave SQL thread */
|
||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#ifndef TO_BE_DELETED
|
||||
/*
|
||||
@@ -1773,14 +1796,14 @@ mysql_execute_command(THD *thd)
|
||||
{
|
||||
if (res < 0 || thd->net.report_error)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (&lex->select_lex != lex->all_selects_list &&
|
||||
lex->unit.create_total_list(thd, lex, &tables, 0))
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
/*
|
||||
When option readonly is set deny operations which change tables.
|
||||
@@ -1795,7 +1818,7 @@ mysql_execute_command(THD *thd)
|
||||
(uc_update_queries[lex->sql_command] > 0))
|
||||
{
|
||||
send_error(thd, ER_CANT_UPDATE_WITH_READLOCK);
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
statistic_increment(com_stat[lex->sql_command],&LOCK_status);
|
||||
@@ -1840,12 +1863,12 @@ mysql_execute_command(THD *thd)
|
||||
if (!(result= new select_send()))
|
||||
{
|
||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
thd->send_explain_fields(result);
|
||||
fix_tables_pointers(lex->all_selects_list);
|
||||
res= mysql_explain_union(thd, &thd->lex.unit, result);
|
||||
res= mysql_explain_union(thd, &thd->lex->unit, result);
|
||||
MYSQL_LOCK *save_lock= thd->lock;
|
||||
thd->lock= (MYSQL_LOCK *)0;
|
||||
if (lex->describe & DESCRIBE_EXTENDED)
|
||||
@@ -2155,7 +2178,7 @@ mysql_execute_command(THD *thd)
|
||||
find_real_table_in_list(tables->next, tables->db, tables->real_name))
|
||||
{
|
||||
net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name);
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (tables->next)
|
||||
@@ -2244,7 +2267,7 @@ mysql_execute_command(THD *thd)
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
{
|
||||
send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION);
|
||||
break;
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
LOCK_ACTIVE_MI;
|
||||
@@ -2257,7 +2280,7 @@ mysql_execute_command(THD *thd)
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
#if defined(DONT_ALLOW_SHOW_COMMANDS)
|
||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||
break;
|
||||
goto error;
|
||||
#else
|
||||
{
|
||||
ulong priv=0;
|
||||
@@ -2356,7 +2379,7 @@ mysql_execute_command(THD *thd)
|
||||
case SQLCOM_SHOW_BINLOGS:
|
||||
#ifdef DONT_ALLOW_SHOW_COMMANDS
|
||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
#else
|
||||
{
|
||||
if (check_global_access(thd, SUPER_ACL))
|
||||
@@ -2369,7 +2392,7 @@ mysql_execute_command(THD *thd)
|
||||
case SQLCOM_SHOW_CREATE:
|
||||
#ifdef DONT_ALLOW_SHOW_COMMANDS
|
||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
#else
|
||||
{
|
||||
if (check_db_used(thd, tables) ||
|
||||
@@ -2398,7 +2421,6 @@ mysql_execute_command(THD *thd)
|
||||
/* ! we write after unlocking the table */
|
||||
if (!res && !lex->no_write_to_binlog)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
@@ -2426,7 +2448,6 @@ mysql_execute_command(THD *thd)
|
||||
/* ! we write after unlocking the table */
|
||||
if (!res && !lex->no_write_to_binlog)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
@@ -2466,7 +2487,6 @@ mysql_execute_command(THD *thd)
|
||||
/* ! we write after unlocking the table */
|
||||
if (!res && !lex->no_write_to_binlog)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
@@ -2484,7 +2504,7 @@ mysql_execute_command(THD *thd)
|
||||
if (select_lex->item_list.elements != lex->value_list.elements)
|
||||
{
|
||||
send_error(thd,ER_WRONG_VALUE_COUNT);
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
}
|
||||
res= mysql_update(thd,tables,
|
||||
select_lex->item_list,
|
||||
@@ -2507,7 +2527,7 @@ mysql_execute_command(THD *thd)
|
||||
if (select_lex->item_list.elements != lex->value_list.elements)
|
||||
{
|
||||
send_error(thd,ER_WRONG_VALUE_COUNT);
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
const char *msg= 0;
|
||||
@@ -2546,7 +2566,7 @@ mysql_execute_command(THD *thd)
|
||||
if (select_lex->item_list.elements != lex->value_list.elements)
|
||||
{
|
||||
send_error(thd,ER_WRONG_VALUE_COUNT);
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
}
|
||||
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
|
||||
select_lex->item_list, lex->value_list,
|
||||
@@ -2646,7 +2666,7 @@ mysql_execute_command(THD *thd)
|
||||
}
|
||||
case SQLCOM_DELETE_MULTI:
|
||||
{
|
||||
TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex.auxilliary_table_list.first;
|
||||
TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
|
||||
TABLE_LIST *auxi;
|
||||
uint table_count=0;
|
||||
multi_delete *result;
|
||||
@@ -2772,7 +2792,7 @@ mysql_execute_command(THD *thd)
|
||||
case SQLCOM_SHOW_DATABASES:
|
||||
#if defined(DONT_ALLOW_SHOW_COMMANDS)
|
||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
#else
|
||||
if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
|
||||
check_global_access(thd, SHOW_DB_ACL))
|
||||
@@ -2815,7 +2835,7 @@ mysql_execute_command(THD *thd)
|
||||
case SQLCOM_SHOW_LOGS:
|
||||
#ifdef DONT_ALLOW_SHOW_COMMANDS
|
||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
#else
|
||||
{
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
@@ -2830,7 +2850,7 @@ mysql_execute_command(THD *thd)
|
||||
/* FALL THROUGH */
|
||||
#ifdef DONT_ALLOW_SHOW_COMMANDS
|
||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
#else
|
||||
{
|
||||
char *db=select_lex->db ? select_lex->db : thd->db;
|
||||
@@ -2879,7 +2899,7 @@ mysql_execute_command(THD *thd)
|
||||
case SQLCOM_SHOW_FIELDS:
|
||||
#ifdef DONT_ALLOW_SHOW_COMMANDS
|
||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
#else
|
||||
{
|
||||
char *db=tables->db;
|
||||
@@ -2906,7 +2926,7 @@ mysql_execute_command(THD *thd)
|
||||
case SQLCOM_SHOW_KEYS:
|
||||
#ifdef DONT_ALLOW_SHOW_COMMANDS
|
||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||
DBUG_VOID_RETURN;
|
||||
goto error;
|
||||
#else
|
||||
{
|
||||
char *db=tables->db;
|
||||
@@ -3098,26 +3118,24 @@ mysql_execute_command(THD *thd)
|
||||
res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_CREATE_FUNCTION:
|
||||
if (check_access(thd,INSERT_ACL,"mysql",0,1,0))
|
||||
break;
|
||||
case SQLCOM_CREATE_FUNCTION: // UDF function
|
||||
{
|
||||
if (check_access(thd,INSERT_ACL,"mysql",0,1,0))
|
||||
break;
|
||||
#ifdef HAVE_DLOPEN
|
||||
if (!(res = mysql_create_function(thd,&lex->udf)))
|
||||
send_ok(thd);
|
||||
sp_head *sph= sp_find_function(thd, &lex->udf.name);
|
||||
if (sph)
|
||||
{
|
||||
net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str);
|
||||
goto error;
|
||||
}
|
||||
if (!(res = mysql_create_function(thd,&lex->udf)))
|
||||
send_ok(thd);
|
||||
#else
|
||||
res= -1;
|
||||
#endif
|
||||
break;
|
||||
case SQLCOM_DROP_FUNCTION:
|
||||
if (check_access(thd,DELETE_ACL,"mysql",0,1,0))
|
||||
break;
|
||||
#ifdef HAVE_DLOPEN
|
||||
if (!(res = mysql_drop_function(thd,&lex->udf.name)))
|
||||
send_ok(thd);
|
||||
#else
|
||||
res= -1;
|
||||
res= -1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
case SQLCOM_DROP_USER:
|
||||
{
|
||||
@@ -3125,7 +3143,6 @@ mysql_execute_command(THD *thd)
|
||||
break;
|
||||
if (!(res= mysql_drop_user(thd, lex->users_list)))
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
@@ -3141,7 +3158,6 @@ mysql_execute_command(THD *thd)
|
||||
break;
|
||||
if (!(res = mysql_revoke_all(thd, lex->users_list)))
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
@@ -3192,14 +3208,11 @@ mysql_execute_command(THD *thd)
|
||||
goto error;
|
||||
if (!(res = mysql_table_grant(thd,tables,lex->users_list, lex->columns,
|
||||
lex->grant,
|
||||
lex->sql_command == SQLCOM_REVOKE)))
|
||||
lex->sql_command == SQLCOM_REVOKE)) &&
|
||||
mysql_bin_log.is_open())
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3214,7 +3227,6 @@ mysql_execute_command(THD *thd)
|
||||
lex->sql_command == SQLCOM_REVOKE);
|
||||
if (!res)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
@@ -3257,7 +3269,6 @@ mysql_execute_command(THD *thd)
|
||||
*/
|
||||
if (!lex->no_write_to_binlog && write_to_binlog)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
@@ -3269,7 +3280,7 @@ mysql_execute_command(THD *thd)
|
||||
break;
|
||||
}
|
||||
case SQLCOM_KILL:
|
||||
kill_one_thread(thd,lex->thread_id);
|
||||
kill_one_thread(thd,lex->thread_id, lex->type & ONLY_KILL_QUERY);
|
||||
break;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
case SQLCOM_SHOW_GRANTS:
|
||||
@@ -3381,16 +3392,257 @@ mysql_execute_command(THD *thd)
|
||||
else
|
||||
res= -1;
|
||||
break;
|
||||
case SQLCOM_CREATE_PROCEDURE:
|
||||
case SQLCOM_CREATE_SPFUNCTION:
|
||||
if (!lex->sphead)
|
||||
{
|
||||
res= -1; // Shouldn't happen
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint namelen;
|
||||
char *name= lex->sphead->name(&namelen);
|
||||
#ifdef HAVE_DLOPEN
|
||||
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
|
||||
{
|
||||
udf_func *udf = find_udf(name, namelen);
|
||||
|
||||
if (udf)
|
||||
{
|
||||
net_printf(thd, ER_UDF_EXISTS, name);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
|
||||
!lex->sphead->m_has_return)
|
||||
{
|
||||
net_printf(thd, ER_SP_NORETURN, name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
res= lex->sphead->create(thd);
|
||||
|
||||
switch (res)
|
||||
{
|
||||
case SP_OK:
|
||||
send_ok(thd);
|
||||
break;
|
||||
case SP_WRITE_ROW_FAILED:
|
||||
net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name);
|
||||
goto error;
|
||||
default:
|
||||
net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLCOM_CALL:
|
||||
{
|
||||
sp_head *sp;
|
||||
|
||||
sp= sp_find_procedure(thd, &lex->udf.name);
|
||||
if (! sp)
|
||||
{
|
||||
net_printf(thd, ER_SP_DOES_NOT_EXIST, "PROCEDURE", lex->udf.name);
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint smrx;
|
||||
LINT_INIT(smrx);
|
||||
|
||||
// In case the arguments are subselects...
|
||||
if (tables && ((res= check_table_access(thd, SELECT_ACL, tables, 0)) ||
|
||||
(res= open_and_lock_tables(thd, tables))))
|
||||
{
|
||||
break;
|
||||
}
|
||||
fix_tables_pointers(lex->all_selects_list);
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
// When executing substatements, they're assumed to send_error when
|
||||
// it happens, but not to send_ok.
|
||||
my_bool nsok= thd->net.no_send_ok;
|
||||
thd->net.no_send_ok= TRUE;
|
||||
#endif
|
||||
if (sp->m_multi_results)
|
||||
{
|
||||
if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
|
||||
{
|
||||
send_error(thd, ER_SP_BADSELECT);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
smrx= thd->server_status & SERVER_MORE_RESULTS_EXISTS;
|
||||
thd->server_status |= SERVER_MORE_RESULTS_EXISTS;
|
||||
}
|
||||
|
||||
res= sp->execute_procedure(thd, &lex->value_list);
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
#endif
|
||||
if (sp->m_multi_results)
|
||||
{
|
||||
if (! smrx)
|
||||
thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
}
|
||||
|
||||
if (res == 0)
|
||||
send_ok(thd);
|
||||
else
|
||||
goto error; // Substatement should already have sent error
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLCOM_ALTER_PROCEDURE:
|
||||
case SQLCOM_ALTER_FUNCTION:
|
||||
{
|
||||
res= -1;
|
||||
uint newname_len= 0;
|
||||
if (lex->name)
|
||||
newname_len= strlen(lex->name);
|
||||
if (newname_len > NAME_LEN)
|
||||
{
|
||||
net_printf(thd, ER_TOO_LONG_IDENT, lex->name);
|
||||
goto error;
|
||||
}
|
||||
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
|
||||
res= sp_update_procedure(thd, lex->udf.name.str, lex->udf.name.length,
|
||||
lex->name, newname_len, lex->comment->str,
|
||||
lex->comment->length, lex->suid);
|
||||
else
|
||||
res= sp_update_function(thd, lex->udf.name.str, lex->udf.name.length,
|
||||
lex->name, newname_len, lex->comment->str,
|
||||
lex->comment->length, lex->suid);
|
||||
switch (res)
|
||||
{
|
||||
case SP_OK:
|
||||
send_ok(thd);
|
||||
break;
|
||||
case SP_KEY_NOT_FOUND:
|
||||
net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex),lex->udf.name);
|
||||
goto error;
|
||||
default:
|
||||
net_printf(thd, ER_SP_CANT_ALTER, SP_COM_STRING(lex),lex->udf.name);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLCOM_DROP_PROCEDURE:
|
||||
case SQLCOM_DROP_FUNCTION:
|
||||
{
|
||||
if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
|
||||
res= sp_drop_procedure(thd, lex->udf.name.str, lex->udf.name.length);
|
||||
else
|
||||
{
|
||||
res= sp_drop_function(thd, lex->udf.name.str, lex->udf.name.length);
|
||||
#ifdef HAVE_DLOPEN
|
||||
if (res == SP_KEY_NOT_FOUND)
|
||||
{
|
||||
udf_func *udf = find_udf(lex->udf.name.str, lex->udf.name.length);
|
||||
if (udf)
|
||||
{
|
||||
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0))
|
||||
goto error;
|
||||
if (!(res = mysql_drop_function(thd,&lex->udf.name)))
|
||||
{
|
||||
send_ok(thd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
switch (res)
|
||||
{
|
||||
case SP_OK:
|
||||
send_ok(thd);
|
||||
break;
|
||||
case SP_KEY_NOT_FOUND:
|
||||
if (lex->drop_if_exists)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
|
||||
SP_COM_STRING(lex), lex->udf.name.str);
|
||||
res= 0;
|
||||
send_ok(thd);
|
||||
break;
|
||||
}
|
||||
net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex),
|
||||
lex->udf.name.str);
|
||||
goto error;
|
||||
default:
|
||||
net_printf(thd, ER_SP_DROP_FAILED, SP_COM_STRING(lex),
|
||||
lex->udf.name.str);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLCOM_SHOW_CREATE_PROC:
|
||||
{
|
||||
res= -1;
|
||||
if (lex->udf.name.length > NAME_LEN)
|
||||
{
|
||||
net_printf(thd, ER_TOO_LONG_IDENT, lex->udf.name.str);
|
||||
goto error;
|
||||
}
|
||||
res= sp_show_create_procedure(thd, &lex->udf.name);
|
||||
if (res == SP_KEY_NOT_FOUND)
|
||||
{
|
||||
net_printf(thd, ER_SP_DOES_NOT_EXIST,
|
||||
SP_COM_STRING(lex), lex->udf.name.str);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLCOM_SHOW_CREATE_FUNC:
|
||||
{
|
||||
if (lex->udf.name.length > NAME_LEN)
|
||||
{
|
||||
net_printf(thd, ER_TOO_LONG_IDENT, lex->udf.name.str);
|
||||
goto error;
|
||||
}
|
||||
res= sp_show_create_function(thd, &lex->udf.name);
|
||||
if (res == SP_KEY_NOT_FOUND)
|
||||
{
|
||||
net_printf(thd, ER_SP_DOES_NOT_EXIST,
|
||||
SP_COM_STRING(lex), lex->udf.name.str);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SQLCOM_SHOW_STATUS_PROC:
|
||||
{
|
||||
res= db_show_status_procedure(thd, (lex->wild ?
|
||||
lex->wild->ptr() : NullS));
|
||||
break;
|
||||
}
|
||||
case SQLCOM_SHOW_STATUS_FUNC:
|
||||
{
|
||||
res= db_show_status_function(thd, (lex->wild ?
|
||||
lex->wild->ptr() : NullS));
|
||||
break;
|
||||
}
|
||||
default: /* Impossible */
|
||||
send_ok(thd);
|
||||
break;
|
||||
}
|
||||
thd->proc_info="query end"; // QQ
|
||||
|
||||
// We end up here if res == 0 and send_ok() has been done,
|
||||
// or res != 0 and no send_error() has yet been done.
|
||||
if (res < 0)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
send_error(thd,thd->killed_errno());
|
||||
DBUG_RETURN(res);
|
||||
|
||||
error:
|
||||
DBUG_VOID_RETURN;
|
||||
// We end up here if send_error() has already been done.
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -3699,10 +3951,10 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize)
|
||||
****************************************************************************/
|
||||
|
||||
void
|
||||
mysql_init_query(THD *thd)
|
||||
mysql_init_query(THD *thd, bool lexonly)
|
||||
{
|
||||
DBUG_ENTER("mysql_init_query");
|
||||
LEX *lex=&thd->lex;
|
||||
LEX *lex=thd->lex;
|
||||
lex->unit.init_query();
|
||||
lex->unit.init_select();
|
||||
lex->unit.thd= thd;
|
||||
@@ -3718,22 +3970,27 @@ mysql_init_query(THD *thd)
|
||||
lex->select_lex.prev= &lex->unit.slave;
|
||||
lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0;
|
||||
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
|
||||
lex->select_lex.init_order();
|
||||
lex->select_lex.group_list.empty();
|
||||
lex->describe= 0;
|
||||
lex->derived_tables= FALSE;
|
||||
lex->lock_option= TL_READ;
|
||||
lex->found_colon= 0;
|
||||
lex->safe_to_cache_query= 1;
|
||||
thd->select_number= lex->select_lex.select_number= 1;
|
||||
thd->free_list= 0;
|
||||
thd->total_warn_count=0; // Warnings for this query
|
||||
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
|
||||
thd->sent_row_count= thd->examined_row_count= 0;
|
||||
thd->is_fatal_error= thd->rand_used= 0;
|
||||
thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
thd->tmp_table_used= 0;
|
||||
if (opt_bin_log)
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
thd->clear_error();
|
||||
if (! lexonly)
|
||||
{
|
||||
thd->select_number= lex->select_lex.select_number= 1;
|
||||
thd->free_list= 0;
|
||||
thd->total_warn_count=0; // Warnings for this query
|
||||
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
|
||||
thd->sent_row_count= thd->examined_row_count= 0;
|
||||
thd->is_fatal_error= thd->rand_used= 0;
|
||||
thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
thd->tmp_table_used= 0;
|
||||
if (opt_bin_log)
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
thd->clear_error();
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@@ -3827,7 +4084,7 @@ void create_select_for_variable(const char *var_name)
|
||||
DBUG_ENTER("create_select_for_variable");
|
||||
|
||||
thd= current_thd;
|
||||
lex= &thd->lex;
|
||||
lex= thd->lex;
|
||||
mysql_init_select(lex);
|
||||
lex->sql_command= SQLCOM_SELECT;
|
||||
tmp.str= (char*) var_name;
|
||||
@@ -3870,7 +4127,16 @@ mysql_parse(THD *thd, char *inBuf, uint length)
|
||||
#endif
|
||||
{
|
||||
if (thd->net.report_error)
|
||||
{
|
||||
send_error(thd, 0, NullS);
|
||||
if (thd->lex->sphead)
|
||||
{
|
||||
if (lex != thd->lex)
|
||||
thd->lex->sphead->restore_lex(thd);
|
||||
delete thd->lex->sphead;
|
||||
thd->lex->sphead= NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_execute_command(thd);
|
||||
@@ -3886,6 +4152,13 @@ mysql_parse(THD *thd, char *inBuf, uint length)
|
||||
thd->is_fatal_error));
|
||||
#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
|
||||
query_cache_abort(&thd->net);
|
||||
if (thd->lex->sphead)
|
||||
{
|
||||
if (lex != thd->lex)
|
||||
thd->lex->sphead->restore_lex(thd);
|
||||
delete thd->lex->sphead;
|
||||
thd->lex->sphead= NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
thd->proc_info="freeing items";
|
||||
@@ -3909,7 +4182,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
||||
uint uint_geom_type)
|
||||
{
|
||||
register create_field *new_field;
|
||||
LEX *lex= &thd->lex;
|
||||
LEX *lex= thd->lex;
|
||||
uint allowed_type_modifier=0;
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
DBUG_ENTER("add_field_to_list");
|
||||
@@ -4238,7 +4511,7 @@ add_proc_to_list(THD* thd, Item *item)
|
||||
*item_ptr= item;
|
||||
order->item=item_ptr;
|
||||
order->free_me=0;
|
||||
thd->lex.proc_list.link_in_list((byte*) order,(byte**) &order->next);
|
||||
thd->lex->proc_list.link_in_list((byte*) order,(byte**) &order->next);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4523,7 +4796,6 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
||||
*/
|
||||
tmp_write_to_binlog= 0;
|
||||
mysql_log.new_file(1);
|
||||
mysql_update_log.new_file(1);
|
||||
mysql_bin_log.new_file(1);
|
||||
mysql_slow_log.new_file(1);
|
||||
#ifdef HAVE_REPLICATION
|
||||
@@ -4623,7 +4895,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
||||
This is written such that we have a short lock on LOCK_thread_count
|
||||
*/
|
||||
|
||||
void kill_one_thread(THD *thd, ulong id)
|
||||
void kill_one_thread(THD *thd, ulong id, bool only_kill_query)
|
||||
{
|
||||
THD *tmp;
|
||||
uint error=ER_NO_SUCH_THREAD;
|
||||
@@ -4645,7 +4917,7 @@ void kill_one_thread(THD *thd, ulong id)
|
||||
!strcmp(thd->user,tmp->user))
|
||||
#endif
|
||||
{
|
||||
tmp->awake(1 /*prepare to die*/);
|
||||
tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
|
||||
error=0;
|
||||
}
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
@@ -4726,11 +4998,11 @@ static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name)
|
||||
bool check_simple_select()
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
if (thd->lex.current_select != &thd->lex.select_lex)
|
||||
if (thd->lex->current_select != &thd->lex->select_lex)
|
||||
{
|
||||
char command[80];
|
||||
strmake(command, thd->lex.yylval->symbol.str,
|
||||
min(thd->lex.yylval->symbol.length, sizeof(command)-1));
|
||||
strmake(command, thd->lex->yylval->symbol.str,
|
||||
min(thd->lex->yylval->symbol.length, sizeof(command)-1));
|
||||
net_printf(thd, ER_CANT_USE_OPTION_HERE, command);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user