1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Merge pilot.blaudden:/home/msvensson/mysql/mysql-5.0

into  pilot.blaudden:/home/msvensson/mysql/mysql-5.0-maint
This commit is contained in:
msvensson@pilot.blaudden
2007-03-01 18:12:56 +01:00
355 changed files with 6707 additions and 4144 deletions

View File

@ -32,6 +32,7 @@
#include "sp_head.h"
#include "sp.h"
#include "sp_cache.h"
#include "sql_trigger.h"
#ifdef HAVE_OPENSSL
/*
@ -65,13 +66,12 @@
extern "C" int gethostname(char *name, int namelen);
#endif
static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
static void decrease_user_connections(USER_CONN *uc);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_multi_update_lock(THD *thd);
static void remove_escape(char *name);
static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
@ -671,6 +671,8 @@ bool is_update_query(enum enum_sql_command command)
safe to test and modify members of the USER_CONN structure.
*/
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
{
time_t check_time = thd->start_time ? thd->start_time : time(NULL);
@ -688,7 +690,6 @@ static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
DBUG_VOID_RETURN;
}
/*
Check if maximum queries per hour limit has been reached
returns 0 if OK.
@ -696,7 +697,6 @@ static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
static bool check_mqh(THD *thd, uint check_command)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool error= 0;
USER_CONN *uc=thd->user_connect;
DBUG_ENTER("check_mqh");
@ -730,11 +730,10 @@ static bool check_mqh(THD *thd, uint check_command)
end:
(void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_RETURN(error);
#else
return (0);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
static void reset_mqh(LEX_USER *lu, bool get_them= 0)
{
@ -1617,7 +1616,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
thd->set_time();
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id=query_id;
thd->query_id= global_query_id;
if (command != COM_STATISTICS && command != COM_PING)
next_query_id();
thread_running++;
@ -1798,7 +1797,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
while (!thd->killed && thd->lex->found_semicolon && !thd->net.report_error)
{
char *packet= thd->lex->found_semicolon;
char *next_packet= thd->lex->found_semicolon;
net->no_send_error= 0;
/*
Multiple queries exits, execute them individually
@ -1806,24 +1805,24 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (thd->lock || thd->open_tables || thd->derived_tables ||
thd->prelocked_mode)
close_thread_tables(thd);
ulong length= (ulong)(packet_end-packet);
ulong length= (ulong)(packet_end - next_packet);
log_slow_statement(thd);
/* Remove garbage at start of query */
while (my_isspace(thd->charset(), *packet) && length > 0)
while (my_isspace(thd->charset(), *next_packet) && length > 0)
{
packet++;
next_packet++;
length--;
}
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_length= length;
thd->query= packet;
thd->query= next_packet;
thd->query_id= next_query_id();
thd->set_time(); /* Reset the query start time. */
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count));
mysql_parse(thd, packet, length);
mysql_parse(thd, next_packet, length);
}
if (!(specialflag & SPECIAL_NO_PRIOR))
@ -1840,16 +1839,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
char *fields, *pend;
/* Locked closure of all tables */
TABLE_LIST *locked_tables= NULL;
TABLE_LIST table_list;
LEX_STRING conv_name;
/* Saved variable value */
my_bool old_innodb_table_locks=
IF_INNOBASE_DB(thd->variables.innodb_table_locks, FALSE);
/* used as fields initializator */
lex_start(thd, 0, 0);
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
&LOCK_status);
bzero((char*) &table_list,sizeof(table_list));
@ -2045,7 +2040,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
STATUS_VAR current_global_status_var;
calc_sum_of_all_status(&current_global_status_var);
ulong uptime = (ulong) (thd->start_time - start_time);
ulong uptime = (ulong) (thd->start_time - server_start_time);
sprintf((char*) buff,
"Uptime: %lu Threads: %d Questions: %lu Slow queries: %lu Opens: %lu Flush tables: %lu Open tables: %u Queries per second avg: %.3f",
uptime,
@ -2092,13 +2087,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
statistic_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION],
&LOCK_status);
enum_mysql_set_option command= (enum_mysql_set_option) uint2korr(packet);
switch (command) {
case MYSQL_OPTION_MULTI_STATEMENTS_ON:
uint opt_command= uint2korr(packet);
switch (opt_command) {
case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
send_eof(thd);
break;
case MYSQL_OPTION_MULTI_STATEMENTS_OFF:
case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
send_eof(thd);
break;
@ -2441,7 +2437,7 @@ mysql_execute_command(THD *thd)
{
bool res= FALSE;
bool need_start_waiting= FALSE; // have protection against global read lock
int result= 0;
int up_result= 0;
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
SELECT_LEX *select_lex= &lex->select_lex;
@ -2507,6 +2503,30 @@ mysql_execute_command(THD *thd)
#ifdef HAVE_REPLICATION
if (unlikely(thd->slave_thread))
{
if (lex->sql_command == SQLCOM_DROP_TRIGGER)
{
/*
When dropping a trigger, we need to load its table name
before checking slave filter rules.
*/
add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
if (!all_tables)
{
/*
If table name cannot be loaded,
it means the trigger does not exists possibly because
CREATE TRIGGER was previously skipped for this trigger
according to slave filtering rules.
Returning success without producing any errors in this case.
*/
DBUG_RETURN(0);
}
// force searching in slave.cc:tables_ok()
all_tables->updating= 1;
}
/*
Check if statment should be skipped because of slave filtering
rules
@ -2585,7 +2605,7 @@ mysql_execute_command(THD *thd)
new Item_int((ulonglong)thd->variables.select_limit);
}
select_result *result=lex->result;
select_result *sel_result=lex->result;
if (all_tables)
{
if (lex->orig_sql_command != SQLCOM_SHOW_STATUS_PROC &&
@ -2612,11 +2632,11 @@ mysql_execute_command(THD *thd)
to prepend EXPLAIN to any query and receive output for it,
even if the query itself redirects the output.
*/
if (!(result= new select_send()))
if (!(sel_result= new select_send()))
goto error;
else
thd->send_explain_fields(result);
res= mysql_explain_union(thd, &thd->lex->unit, result);
thd->send_explain_fields(sel_result);
res= mysql_explain_union(thd, &thd->lex->unit, sel_result);
if (lex->describe & DESCRIBE_EXTENDED)
{
char buff[1024];
@ -2627,17 +2647,17 @@ mysql_execute_command(THD *thd)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_YES, str.ptr());
}
result->send_eof();
delete result;
sel_result->send_eof();
delete sel_result;
}
else
{
if (!result && !(result= new select_send()))
if (!sel_result && !(sel_result= new select_send()))
goto error;
query_cache_store_query(thd, all_tables);
res= handle_select(thd, lex, result, 0);
if (result != lex->result)
delete result;
res= handle_select(thd, lex, sel_result, 0);
if (sel_result != lex->result)
delete sel_result;
}
}
break;
@ -2990,7 +3010,7 @@ mysql_execute_command(THD *thd)
}
if (select_lex->item_list.elements) // With select
{
select_result *result;
select_result *sel_result;
select_lex->options|= SELECT_NO_UNLOCK;
unit->set_limit(select_lex);
@ -3032,19 +3052,19 @@ mysql_execute_command(THD *thd)
select_create is currently not re-execution friendly and
needs to be created for every execution of a PS/SP.
*/
if ((result= new select_create(create_table,
&create_info,
&alter_info,
select_lex->item_list,
lex->duplicates,
lex->ignore)))
if ((sel_result= new select_create(create_table,
&create_info,
&alter_info,
select_lex->item_list,
lex->duplicates,
lex->ignore)))
{
/*
CREATE from SELECT give its SELECT_LEX for SELECT,
and item_list belong to SELECT
*/
res= handle_select(thd, lex, result, 0);
delete result;
res= handle_select(thd, lex, sel_result, 0);
delete sel_result;
}
}
}
@ -3399,22 +3419,23 @@ end_with_restore_list:
break;
DBUG_ASSERT(select_lex->offset_limit == 0);
unit->set_limit(select_lex);
res= (result= mysql_update(thd, all_tables,
select_lex->item_list,
lex->value_list,
select_lex->where,
select_lex->order_list.elements,
(ORDER *) select_lex->order_list.first,
unit->select_limit_cnt,
lex->duplicates, lex->ignore));
res= (up_result= mysql_update(thd, all_tables,
select_lex->item_list,
lex->value_list,
select_lex->where,
select_lex->order_list.elements,
(ORDER *) select_lex->order_list.first,
unit->select_limit_cnt,
lex->duplicates, lex->ignore));
/* mysql_update return 2 if we need to switch to multi-update */
if (result != 2)
if (up_result != 2)
break;
/* Fall through */
case SQLCOM_UPDATE_MULTI:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
/* if we switched from normal update, rights are checked */
if (result != 2)
if (up_result != 2)
{
if ((res= multi_update_precheck(thd, all_tables)))
break;
@ -3498,7 +3519,7 @@ end_with_restore_list:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT:
{
select_result *result;
select_result *sel_result;
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if ((res= insert_precheck(thd, all_tables)))
break;
@ -3527,13 +3548,15 @@ end_with_restore_list:
select_lex->context.table_list=
select_lex->context.first_name_resolution_table= second_table;
res= mysql_insert_select_prepare(thd);
if (!res && (result= new select_insert(first_table, first_table->table,
&lex->field_list,
&lex->update_list,
&lex->value_list,
lex->duplicates, lex->ignore)))
if (!res && (sel_result= new select_insert(first_table,
first_table->table,
&lex->field_list,
&lex->update_list,
&lex->value_list,
lex->duplicates,
lex->ignore)))
{
res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
/*
Invalidate the table in the query cache if something changed
after unlocking when changes become visible.
@ -3551,7 +3574,7 @@ end_with_restore_list:
first_table->next_local= save_table;
thd->lock=0;
}
delete result;
delete sel_result;
}
/* revert changes for SP */
select_lex->table_list.first= (byte*) first_table;
@ -3616,7 +3639,7 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *aux_tables=
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
multi_delete *result;
multi_delete *del_result;
if (!thd->locked_tables &&
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
@ -3641,8 +3664,8 @@ end_with_restore_list:
if ((res= mysql_multi_delete_prepare(thd)))
goto error;
if (!thd->is_fatal_error && (result= new multi_delete(aux_tables,
lex->table_count)))
if (!thd->is_fatal_error &&
(del_result= new multi_delete(aux_tables, lex->table_count)))
{
res= mysql_select(thd, &select_lex->ref_pointer_array,
select_lex->get_table_list(),
@ -3654,8 +3677,8 @@ end_with_restore_list:
select_lex->options | thd->options |
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE,
result, unit, select_lex);
delete result;
del_result, unit, select_lex);
delete del_result;
}
else
res= TRUE; // Error
@ -4333,7 +4356,7 @@ end_with_restore_list:
{
uint namelen;
char *name;
int result= SP_INTERNAL_ERROR;
int sp_result= SP_INTERNAL_ERROR;
DBUG_ASSERT(lex->sphead != 0);
DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
@ -4406,18 +4429,18 @@ end_with_restore_list:
if (!lex->definer)
{
bool res= FALSE;
bool local_res= FALSE;
Query_arena original_arena;
Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
if (!(lex->definer= create_default_definer(thd)))
res= TRUE;
local_res= TRUE;
if (ps_arena)
thd->restore_active_arena(ps_arena, &original_arena);
/* Error has been already reported. */
if (res)
if (local_res)
goto create_sp_error;
if (thd->slave_thread)
@ -4457,8 +4480,8 @@ end_with_restore_list:
}
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
res= (result= lex->sphead->create(thd));
switch (result) {
res= (sp_result= lex->sphead->create(thd));
switch (sp_result) {
case SP_OK:
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* only add privileges if really neccessary */
@ -4498,7 +4521,7 @@ create_sp_error:
lex->unit.cleanup();
delete lex->sphead;
lex->sphead= 0;
if (result != SP_OK )
if (sp_result != SP_OK )
goto error;
send_ok(thd);
break; /* break super switch */
@ -4610,7 +4633,7 @@ create_sp_error:
case SQLCOM_ALTER_PROCEDURE:
case SQLCOM_ALTER_FUNCTION:
{
int result;
int sp_result;
sp_head *sp;
st_sp_chistics chistics;
@ -4625,7 +4648,7 @@ create_sp_error:
if (! sp)
{
if (lex->spname->m_db.str)
result= SP_KEY_NOT_FOUND;
sp_result= SP_KEY_NOT_FOUND;
else
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
@ -4650,7 +4673,7 @@ create_sp_error:
{
my_message(ER_BINLOG_UNSAFE_ROUTINE,
ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
result= SP_INTERNAL_ERROR;
sp_result= SP_INTERNAL_ERROR;
}
else
{
@ -4660,15 +4683,15 @@ create_sp_error:
follow the restrictions that log-bin-trust-function-creators=0
already puts on CREATE FUNCTION.
*/
/* Conditionally writes to binlog */
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
/* Conditionally writes to binlog */
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
sp_result= sp_update_procedure(thd, lex->spname,
&lex->sp_chistics);
else
/* Conditionally writes to binlog */
result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
sp_result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
}
}
switch (result)
switch (sp_result)
{
case SP_OK:
send_ok(thd);
@ -4687,13 +4710,13 @@ create_sp_error:
case SQLCOM_DROP_PROCEDURE:
case SQLCOM_DROP_FUNCTION:
{
int result;
int sp_result;
int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
result= sp_routine_exists_in_table(thd, type, lex->spname);
sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
mysql_reset_errors(thd, 0);
if (result == SP_OK)
if (sp_result == SP_OK)
{
char *db= lex->spname->m_db.str;
char *name= lex->spname->m_name.str;
@ -4714,12 +4737,11 @@ create_sp_error:
ER(ER_PROC_AUTO_REVOKE_FAIL));
}
#endif
/* Conditionally writes to binlog */
if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
/* Conditionally writes to binlog */
result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */
sp_result= sp_drop_procedure(thd, lex->spname);
else
/* Conditionally writes to binlog */
result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */
sp_result= sp_drop_function(thd, lex->spname);
}
else
{
@ -4743,16 +4765,15 @@ create_sp_error:
}
#endif
if (lex->spname->m_db.str)
result= SP_KEY_NOT_FOUND;
sp_result= SP_KEY_NOT_FOUND;
else
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
goto error;
}
}
res= result;
switch (result)
{
res= sp_result;
switch (sp_result) {
case SP_OK:
send_ok(thd);
break;
@ -5388,7 +5409,9 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
{
uint found=0;
ulong found_access=0;
#ifndef EMBEDDED_LIBRARY
TABLE_LIST *org_tables= tables;
#endif
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
/*
@ -6592,18 +6615,18 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
0 on success
*/
bool st_select_lex_unit::add_fake_select_lex(THD *thd)
bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
{
SELECT_LEX *first_sl= first_select();
DBUG_ENTER("add_fake_select_lex");
DBUG_ASSERT(!fake_select_lex);
if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX()))
if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
DBUG_RETURN(1);
fake_select_lex->include_standalone(this,
(SELECT_LEX_NODE**)&fake_select_lex);
fake_select_lex->select_number= INT_MAX;
fake_select_lex->parent_lex= thd->lex; /* Used in init_query. */
fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
fake_select_lex->make_empty_select();
fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
fake_select_lex->select_limit= 0;
@ -6623,9 +6646,9 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd)
*/
global_parameters= fake_select_lex;
fake_select_lex->no_table_names_allowed= 1;
thd->lex->current_select= fake_select_lex;
thd_arg->lex->current_select= fake_select_lex;
}
thd->lex->pop_context();
thd_arg->lex->pop_context();
DBUG_RETURN(0);
}