diff options
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 136 |
1 files changed, 80 insertions, 56 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6424b97b422..0cebde364f7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -99,7 +99,17 @@ static void init_signals(void) } #endif -inline bool end_active_trans(THD *thd) +static void unlock_locked_tables(THD *thd) +{ + if (thd->locked_tables) + { + thd->lock=thd->locked_tables; + thd->locked_tables=0; // Will be automaticly closed + close_thread_tables(thd); // Free tables + } +} + +static bool end_active_trans(THD *thd) { int error=0; if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN | @@ -698,7 +708,7 @@ pthread_handler_decl(handle_one_connection,arg) (net->last_errno ? ER(net->last_errno) : ER(ER_UNKNOWN_ERROR))); send_error(net,net->last_errno,NullS); - thread_safe_increment(aborted_threads,&LOCK_status); + statistic_increment(aborted_threads,&LOCK_status); } end_thread: @@ -911,7 +921,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->lex.select_lex.options=0; // We store status here switch (command) { case COM_INIT_DB: - thread_safe_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status); + statistic_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status); if (!mysql_change_db(thd,packet)) mysql_log.write(thd,command,"%s",thd->db); break; @@ -923,7 +933,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_TABLE_DUMP: { - thread_safe_increment(com_other, &LOCK_status); + statistic_increment(com_other, &LOCK_status); slow_command = TRUE; uint db_len = *(uchar*)packet; uint tbl_len = *(uchar*)(packet + db_len + 1); @@ -940,7 +950,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_CHANGE_USER: { - thread_safe_increment(com_other,&LOCK_status); + thd->change_user(); + clear_error_message(thd); // If errors from rollback + + statistic_increment(com_other,&LOCK_status); char *user= (char*) packet; char *passwd= strend(user)+1; char *db= strend(passwd)+1; @@ -1020,7 +1033,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { char *fields; TABLE_LIST table_list; - thread_safe_increment(com_stat[SQLCOM_SHOW_FIELDS],&LOCK_status); + statistic_increment(com_stat[SQLCOM_SHOW_FIELDS],&LOCK_status); bzero((char*) &table_list,sizeof(table_list)); if (!(table_list.db=thd->db)) { @@ -1055,7 +1068,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_CREATE_DB: // QQ: To be removed { - thread_safe_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status); + statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status); char *db=thd->strdup(packet); // null test to handle EOM if (!db || !strip_sp(db) || check_db_name(db)) @@ -1073,7 +1086,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_DROP_DB: // QQ: To be removed { - thread_safe_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status); + statistic_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status); char *db=thd->strdup(packet); // null test to handle EOM if (!db || !strip_sp(db) || check_db_name(db)) @@ -1094,7 +1107,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_BINLOG_DUMP: { - thread_safe_increment(com_other,&LOCK_status); + statistic_increment(com_other,&LOCK_status); slow_command = TRUE; if (check_global_access(thd, REPL_SLAVE_ACL)) break; @@ -1118,7 +1131,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_REFRESH: { - thread_safe_increment(com_stat[SQLCOM_FLUSH],&LOCK_status); + statistic_increment(com_stat[SQLCOM_FLUSH],&LOCK_status); ulong options= (ulong) (uchar) packet[0]; if (check_global_access(thd,RELOAD_ACL)) break; @@ -1130,7 +1143,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } case COM_SHUTDOWN: - thread_safe_increment(com_other,&LOCK_status); + statistic_increment(com_other,&LOCK_status); if (check_global_access(thd,SHUTDOWN_ACL)) break; /* purecov: inspected */ DBUG_PRINT("quit",("Got shutdown command")); @@ -1153,7 +1166,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_STATISTICS: { mysql_log.write(thd,command,NullS); - thread_safe_increment(com_stat[SQLCOM_SHOW_STATUS],&LOCK_status); + statistic_increment(com_stat[SQLCOM_SHOW_STATUS],&LOCK_status); char buff[200]; ulong uptime = (ulong) (thd->start_time - start_time); sprintf((char*) buff, @@ -1172,11 +1185,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } case COM_PING: - thread_safe_increment(com_other,&LOCK_status); + statistic_increment(com_other,&LOCK_status); send_ok(net); // Tell client we are alive break; case COM_PROCESS_INFO: - thread_safe_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status); + statistic_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status); if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL)) break; mysql_log.write(thd,command,NullS); @@ -1185,13 +1198,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; case COM_PROCESS_KILL: { - thread_safe_increment(com_stat[SQLCOM_KILL],&LOCK_status); + statistic_increment(com_stat[SQLCOM_KILL],&LOCK_status); ulong id=(ulong) uint4korr(packet); kill_one_thread(thd,id); break; } case COM_DEBUG: - thread_safe_increment(com_other,&LOCK_status); + statistic_increment(com_other,&LOCK_status); if (check_global_access(thd, SUPER_ACL)) break; /* purecov: inspected */ mysql_print_status(thd); @@ -1291,7 +1304,7 @@ mysql_execute_command(void) !tables_ok(thd,tables))) DBUG_VOID_RETURN; - thread_safe_increment(com_stat[lex->sql_command],&LOCK_status); + statistic_increment(com_stat[lex->sql_command],&LOCK_status); switch (lex->sql_command) { case SQLCOM_SELECT: { @@ -1355,6 +1368,8 @@ mysql_execute_command(void) Normal select: Change lock if we are using SELECT HIGH PRIORITY, FOR UPDATE or IN SHARE MODE + + TODO: Delete the following loop when locks is set by sql_yacc */ TABLE_LIST *table; for (table = tables ; table ; table=table->next) @@ -1561,6 +1576,7 @@ mysql_execute_command(void) TABLE_LIST *table; if (check_table_access(thd, SELECT_ACL, tables->next)) goto error; // Error message is given + /* TODO: Delete the following loop when locks is set by sql_yacc */ for (table = tables->next ; table ; table=table->next) table->lock_type= lex->lock_option; } @@ -1802,18 +1818,13 @@ mysql_execute_command(void) } if (select_lex->table_list.elements == 1) { - res = mysql_update(thd,tables, - select_lex->item_list, - lex->value_list, - select_lex->where, - (ORDER *) select_lex->order_list.first, - select_lex->select_limit, - lex->duplicates, - lex->lock_option); - -#ifdef DELETE_ITEMS - delete select_lex->where; -#endif + res= mysql_update(thd,tables, + select_lex->item_list, + lex->value_list, + select_lex->where, + (ORDER *) select_lex->order_list.first, + select_lex->select_limit, + lex->duplicates); } else { @@ -1824,10 +1835,7 @@ mysql_execute_command(void) lex->sql_command=SQLCOM_MULTI_UPDATE; for (auxi=(TABLE_LIST*) tables, table_count=0 ; auxi ; auxi=auxi->next) - { table_count++; - auxi->lock_type=TL_WRITE; - } if (select_lex->order_list.elements) msg="ORDER BY"; else if (select_lex->select_limit && select_lex->select_limit != @@ -1848,8 +1856,7 @@ mysql_execute_command(void) !setup_fields(thd,tables,lex->value_list,0,0,0) && ! thd->fatal_error && (result=new multi_update(thd,tables,select_lex->item_list, - lex->duplicates, lex->lock_option, - table_count))) + lex->duplicates, table_count))) { List <Item> total_list; List_iterator <Item> field_list(select_lex->item_list); @@ -1880,8 +1887,7 @@ mysql_execute_command(void) if (grant_option && check_grant(thd,INSERT_ACL,tables)) goto error; res = mysql_insert(thd,tables,lex->field_list,lex->many_values, - lex->duplicates, - lex->lock_option); + lex->duplicates); break; case SQLCOM_REPLACE: if (check_access(thd,INSERT_ACL | DELETE_ACL, @@ -1892,8 +1898,7 @@ mysql_execute_command(void) goto error; res = mysql_insert(thd,tables,lex->field_list,lex->many_values, - DUP_REPLACE, - lex->lock_option); + DUP_REPLACE); break; case SQLCOM_REPLACE_SELECT: case SQLCOM_INSERT_SELECT: @@ -1928,8 +1933,8 @@ mysql_execute_command(void) net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name); DBUG_VOID_RETURN; } - tables->lock_type=TL_WRITE; // update first table { + /* TODO: Delete the following loop when locks is set by sql_yacc */ TABLE_LIST *table; for (table = tables->next ; table ; table=table->next) table->lock_type= lex->lock_option; @@ -1972,8 +1977,7 @@ mysql_execute_command(void) tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); res = mysql_delete(thd,tables, select_lex->where, (ORDER*) select_lex->order_list.first, - select_lex->select_limit, lex->lock_option, - select_lex->options); + select_lex->select_limit, select_lex->options); break; } case SQLCOM_DELETE_MULTI: @@ -2009,12 +2013,12 @@ mysql_execute_command(void) net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name); goto error; } - auxi->lock_type=walk->lock_type=TL_WRITE; + walk->lock_type= auxi->lock_type; auxi->table= (TABLE *) walk; // Remember corresponding table } if (add_item_to_list(new Item_null())) { - res = -1; + res= -1; break; } tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); @@ -2025,7 +2029,6 @@ mysql_execute_command(void) for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) auxi->table= ((TABLE_LIST*) auxi->table)->table; if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables, - lex->lock_option, table_count))) { res=mysql_select(thd,tables,select_lex->item_list, @@ -2212,11 +2215,7 @@ mysql_execute_command(void) send_ok(&thd->net); break; case SQLCOM_UNLOCK_TABLES: - if (thd->locked_tables) - { - thd->lock=thd->locked_tables; - thd->locked_tables=0; // Will be automaticly closed - } + unlock_locked_tables(thd); if (thd->options & OPTION_TABLE_LOCK) { end_active_trans(thd); @@ -2227,12 +2226,7 @@ mysql_execute_command(void) send_ok(&thd->net); break; case SQLCOM_LOCK_TABLES: - if (thd->locked_tables) - { - thd->lock=thd->locked_tables; - thd->locked_tables=0; // Will be automaticly closed - close_thread_tables(thd); - } + unlock_locked_tables(thd); if (check_db_used(thd,tables) || end_active_trans(thd)) goto error; if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, tables)) @@ -3258,6 +3252,37 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, DBUG_RETURN(ptr); } +/* + Set lock for all tables in current select level + + SYNOPSIS: + set_lock_for_tables() + lock_type Lock to set for tables + + NOTE: + If lock is a write lock, then tables->updating is set 1 + This is to get tables_ok to know that the table is updated by the + query +*/ + +void set_lock_for_tables(thr_lock_type lock_type) +{ + THD *thd=current_thd; + bool for_update= lock_type >= TL_READ_NO_INSERT; + DBUG_ENTER("set_lock_for_tables"); + DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type, + for_update)); + + for (TABLE_LIST *tables= (TABLE_LIST*) thd->lex.select->table_list.first ; + tables ; + tables=tables->next) + { + tables->lock_type= lock_type; + tables->updating= for_update; + } + DBUG_VOID_RETURN; +} + /* ** This is used for UNION to create a new table list of all used tables @@ -3301,7 +3326,6 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) if (!cursor) { /* Add not used table to the total table list */ - aux->lock_type= lex->lock_option; if (!(cursor = (TABLE_LIST *) thd->memdup((char*) aux, sizeof(*aux)))) { |