diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 3 | ||||
-rw-r--r-- | sql/item.cc | 6 | ||||
-rw-r--r-- | sql/log_event.cc | 10 | ||||
-rw-r--r-- | sql/log_event.h | 6 | ||||
-rw-r--r-- | sql/mysqld.cc | 1 | ||||
-rw-r--r-- | sql/set_var.cc | 6 | ||||
-rw-r--r-- | sql/sql_base.cc | 19 | ||||
-rw-r--r-- | sql/sql_cache.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 11 | ||||
-rw-r--r-- | sql/sql_derived.cc | 9 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 4 | ||||
-rw-r--r-- | sql/sql_table.cc | 16 | ||||
-rw-r--r-- | sql/sql_union.cc | 7 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 26 |
19 files changed, 85 insertions, 50 deletions
diff --git a/sql/field.cc b/sql/field.cc index 9acf2e14829..be565e2e869 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2797,7 +2797,6 @@ double Field_timestamp::val_real(void) longlong Field_timestamp::val_int(void) { - uint len,pos; int part_time; uint32 temp; time_t time_arg; @@ -2845,6 +2844,7 @@ String *Field_timestamp::val_str(String *val_buffer, val_buffer->alloc(field_length+1); char *to=(char*) val_buffer->ptr(),*end=to+field_length; val_buffer->length(field_length); + val_buffer->set_charset(val_ptr->charset()); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -3926,7 +3926,6 @@ double Field_string::val_real(void) longlong Field_string::val_int(void) { - longlong value; CHARSET_INFO *cs=charset(); return my_strntoll(cs,ptr,field_length,NULL,10); } diff --git a/sql/item.cc b/sql/item.cc index 461f2ba9de5..55aa12b146e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -173,7 +173,7 @@ const char *Item_ident::full_name() const char *tmp; if (!table_name) return field_name ? field_name : name ? name : "tmp_field"; - if (db_name) + if (db_name && db_name[0]) { tmp=(char*) sql_alloc((uint) strlen(db_name)+(uint) strlen(table_name)+ (uint) strlen(field_name)+3); @@ -563,8 +563,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item **refer= (Item **)not_found_item; // Prevent using outer fields in subselects, that is not supported now SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select; - if (cursel->master_unit()->first_select()->linkage != - DERIVED_TABLE_TYPE) + if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE) for (SELECT_LEX *sl=cursel->outer_select(); sl; sl= sl->outer_select()) @@ -598,7 +597,6 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) (char *)field_name); if (!r) return 1; - int res; if (r->check_cols(1) || r->fix_fields(thd, tables, ref)) return 1; r->depended_from= last; diff --git a/sql/log_event.cc b/sql/log_event.cc index d56bbe53847..a01b1ee6170 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -732,7 +732,9 @@ int Query_log_event::write_data(IO_CACHE* file) #ifndef MYSQL_CLIENT Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, bool using_trans) - :Log_event(thd_arg, 0, using_trans), data_buf(0), query(query_arg), + :Log_event(thd_arg, !thd_arg->lex.tmp_table_used ? + 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), + data_buf(0), query(query_arg), db(thd_arg->db), q_len((uint32) query_length), error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno), thread_id(thd_arg->thread_id) @@ -814,6 +816,8 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) *end++=';'; *end++='\n'; my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME)); + if (flags & LOG_EVENT_THREAD_SPECIFIC_F) + fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id); my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME)); fprintf(file, ";\n"); } @@ -849,7 +853,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) thd->query_error= 0; // clear error thd->clear_error(); - thd->slave_proxy_id = thread_id; // for temp tables + thd->variables.pseudo_thread_id= thread_id; // for temp tables /* Sanity check to make sure the master did not get a really bad @@ -1468,7 +1472,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli) ex.skip_lines = skip_lines; List<Item> field_list; set_fields(field_list); - thd->slave_proxy_id = thd->thread_id; + thd->variables.pseudo_thread_id= thd->thread_id; if (net) { // mysql_load will use thd->net to read the file diff --git a/sql/log_event.h b/sql/log_event.h index c4f93c7a9b6..ec3b4819e74 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -212,8 +212,10 @@ struct sql_ex_info #define BINLOG_MAGIC "\xfe\x62\x69\x6e" -#define LOG_EVENT_TIME_F 0x1 -#define LOG_EVENT_FORCED_ROTATE_F 0x2 +#define LOG_EVENT_TIME_F 0x1 +#define LOG_EVENT_FORCED_ROTATE_F 0x2 +#define LOG_EVENT_THREAD_SPECIFIC_F 0x4 /* query depends on thread + (for example: TEMPORARY TABLE) */ enum Log_event_type { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 694f1a49f95..35d1951b9d6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1896,6 +1896,7 @@ int main(int argc, char **argv) set_options(); get_options(argc,argv); + max_system_variables.pseudo_thread_id= (ulong)~0; if (opt_log || opt_update_log || opt_slow_log || opt_bin_log) strcat(server_version,"-log"); DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname, diff --git a/sql/set_var.cc b/sql/set_var.cc index 3404df1c56a..c7dfb63a86f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -21,6 +21,8 @@ - If the variable is thread specific, add it to 'system_variables' struct. If not, add it to mysqld.cc and an declaration in 'mysql_priv.h' + - Don't forget to initialize new fields in global_system_variables and + max_system_variables! - Use one of the 'sys_var... classes from set_var.h or write a specific one for the variable type. - Define it in the 'variable definition list' in this file. @@ -154,6 +156,8 @@ sys_var_thd_ulong sys_max_error_count("max_error_count", &SV::max_error_count); sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size", &SV::max_heap_table_size); +sys_var_thd_ulong sys_pseudo_thread_id("pseudo_thread_id", + &SV::pseudo_thread_id); sys_var_thd_ulonglong sys_max_join_size("max_join_size", &SV::max_join_size, fix_max_join_size); @@ -364,6 +368,7 @@ sys_var *sys_variables[]= &sys_net_retry_count, &sys_net_wait_timeout, &sys_net_write_timeout, + &sys_pseudo_thread_id, &sys_query_cache_size, #ifdef HAVE_QUERY_CACHE &sys_query_cache_limit, @@ -512,6 +517,7 @@ struct show_var_st init_vars[]= { {"pid_file", (char*) pidfile_name, SHOW_CHAR}, {"port", (char*) &mysql_port, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, + {sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS}, {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS}, {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS}, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 87cc0d616a9..3b1797e2dd0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -554,7 +554,7 @@ TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name) uint key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1; TABLE *table,**prev; - int4store(key+key_length,thd->slave_proxy_id); + int4store(key+key_length,thd->variables.pseudo_thread_id); key_length += 4; prev= &thd->temporary_tables; @@ -594,7 +594,7 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db, (strmov((table->real_name=strmov(table->table_cache_key=key, db)+1), table_name) - table->table_cache_key)+1; - int4store(key+table->key_length,thd->slave_proxy_id); + int4store(key+table->key_length,thd->variables.pseudo_thread_id); table->key_length += 4; return 0; } @@ -748,7 +748,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, if (thd->killed) DBUG_RETURN(0); key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1; - int4store(key + key_length, thd->slave_proxy_id); + int4store(key + key_length, thd->variables.pseudo_thread_id); for (table=thd->temporary_tables; table ; table=table->next) { @@ -762,6 +762,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, DBUG_RETURN(0); } table->query_id=thd->query_id; + thd->lex.tmp_table_used= 1; goto reset; } } @@ -1562,7 +1563,7 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db, +1), table_name) - tmp_table->table_cache_key)+1; int4store(tmp_table->table_cache_key + tmp_table->key_length, - thd->slave_proxy_id); + thd->variables.pseudo_thread_id); tmp_table->key_length += 4; if (link_in_list) @@ -1707,7 +1708,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, if (!found_table && report_error) { char buff[NAME_LEN*2+1]; - if (db) + if (db && db[0]) { strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS); table_name=buff; @@ -1735,6 +1736,14 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, bool allow_rowid= tables && !tables->next; // Only one table for (; tables ; tables=tables->next) { + if (!tables->table) + { + if (report_error) + my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), + item->full_name(),thd->where); + return (Field*) not_found_field; + } + Field *field=find_field_in_table(thd,tables->table,name,length, grant_option && !thd->master_access, allow_rowid); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index aa0f5824b4e..1cfbbf74da6 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1062,6 +1062,8 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used, for (; tables_used; tables_used=tables_used->next) { DBUG_ASSERT(!using_transactions || tables_used->table!=0); + if (tables_used->derived) + continue; if (using_transactions && tables_used->table->file->has_transactions()) /* diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0ab47951074..3ca1f4827ff 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -100,7 +100,7 @@ THD::THD():user_time(0), fatal_error(0), start_time=(time_t) 0; current_linfo = 0; slave_thread = 0; - slave_proxy_id = 0; + variables.pseudo_thread_id= 0; file_id = 0; cond_count=0; warn_id= 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 3abcf12e4b7..ab9230e5f01 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -370,6 +370,12 @@ struct system_variables ulong tmp_table_size; ulong tx_isolation; + /* + In slave thread we need to know in behalf of which + thread the query is being run to replicate temp tables properly + */ + ulong pseudo_thread_id; + my_bool log_warnings; my_bool low_priority_updates; @@ -525,11 +531,6 @@ public: each thread that is using LOG_INFO needs to adjust the pointer to it */ LOG_INFO* current_linfo; - /* - In slave thread we need to know in behalf of which - thread the query is being run to replicate temp tables properly - */ - ulong slave_proxy_id; NET* slave_net; // network connection from slave -> m. my_off_t log_pos; /* Used by the sys_var class to store temporary values */ diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index f7d845e9e36..54179a5e25c 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -168,14 +168,9 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) tables->table_list->table=tables->table; // to fix a problem in EXPLAIN } else - { - if (is_union) - unit->exclude(); - else - sl->exclude(); - } + unit->exclude(); t->db=(char *)""; - t->derived=(SELECT_LEX *)0; // just in case ... + t->derived=(SELECT_LEX *)1; // just in case ... table->file->info(HA_STATUS_VARIABLE); } } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ddbb562bdca..c0e19e64363 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -171,6 +171,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->slave_thd_opt=0; lex->sql_command=SQLCOM_END; lex->safe_to_cache_query= 1; + lex->tmp_table_used= 0; bzero(&lex->mi,sizeof(lex->mi)); return lex; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6e5fd6765fb..9b8f4a47515 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -461,6 +461,7 @@ typedef struct st_lex uint slave_thd_opt; CHARSET_INFO *charset; char *help_arg; + bool tmp_table_used; } LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index de976076a33..c0b33153dab 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1461,7 +1461,6 @@ mysql_execute_command(THD *thd) int res= 0; LEX *lex= &thd->lex; TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first; - TABLE_LIST *cursor; SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); @@ -1803,7 +1802,6 @@ mysql_execute_command(THD *thd) } if (tables->next) { - TABLE_LIST *table; if (check_table_access(thd, SELECT_ACL, tables->next)) goto error; // Error message is given } @@ -3007,6 +3005,7 @@ mysql_init_query(THD *thd) lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list); lex->olap=lex->describe=0; lex->derived_tables= false; + lex->lock_option=TL_READ; thd->check_loops_counter= thd->select_number= lex->select_lex.select_number= 1; thd->free_list= 0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9ee8af08ae4..4ac55c75e3a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7525,7 +7525,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, JOIN_TAB *tab=join->join_tab+i; TABLE *table=tab->table; char buff[512],*buff_ptr=buff; - char buff1[512], buff2[512], buff3[512]; + char buff1[512], buff2[512]; String tmp1(buff1,sizeof(buff1),default_charset_info); String tmp2(buff2,sizeof(buff2),default_charset_info); tmp1.length(0); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ebade0111b0..2b51b687a73 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -841,7 +841,6 @@ int mysqld_show_keys(THD *thd, TABLE_LIST *table_list) { TABLE *table; - char buff[256]; Protocol *protocol= thd->protocol; DBUG_ENTER("mysqld_show_keys"); DBUG_PRINT("enter",("db: %s table: %s",table_list->db, @@ -1329,7 +1328,6 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) time_t now= time(0); while ((thd_info=thread_infos.get())) { - char buff[20],*end; protocol->prepare_for_resend(); protocol->store((ulonglong) thd_info->thread_id); protocol->store(thd_info->user); @@ -1469,7 +1467,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, end= int10_to_str((long) thd->query_id, buff, 10); break; case SHOW_RPL_STATUS: - end= int10_to_str((long) rpl_status_type[(int)rpl_status], buff, 10); + end= strmov(buff, rpl_status_type[(int)rpl_status]); break; case SHOW_SLAVE_RUNNING: { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7cb1cee7e3c..cb9768aaa5c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -190,6 +190,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, wrong_tables.append(String(table->real_name,default_charset_info)); } } + thd->lex.tmp_table_used= tmp_table_deleted; if (some_tables_deleted || tmp_table_deleted) { query_cache_invalidate3(thd, tables, 0); @@ -814,6 +815,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, (void) rm_temporary_table(create_info->db_type, path); goto end; } + thd->lex.tmp_table_used= 1; } if (!tmp_table && !no_log) { @@ -1413,8 +1415,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, check_table_name(src_table,table_ident->table.length)) || table_ident->db.str && check_db_name((src_db= table_ident->db.str))) { - net_printf(thd,ER_WRONG_TABLE_NAME,src_table); - DBUG_RETURN(0); + my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); + DBUG_RETURN(-1); } if ((tmp_table= find_temporary_table(thd, src_db, src_table))) @@ -1470,14 +1472,16 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, { if (err || !open_temporary_table(thd, dst_path, db, table_name, 1)) { - (void) rm_temporary_table(create_info->db_type, dst_path); - DBUG_RETURN(-1); + (void) rm_temporary_table(create_info->db_type, + dst_path); /* purecov: inspected */ + DBUG_RETURN(-1); /* purecov: inspected */ } } else if (err) { - (void) quick_rm_table(create_info->db_type, db, table_name); - DBUG_RETURN(-1); + (void) quick_rm_table(create_info->db_type, db, + table_name); /* purecov: inspected */ + DBUG_RETURN(-1); /* purecov: inspected */ } DBUG_RETURN(0); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 10175bfe345..cdd34977e5a 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -279,9 +279,10 @@ int st_select_lex_unit::exec() } if (!thd->fatal_error) // Check if EOM { - offset_limit_cnt= global_parameters->offset_limit; - select_limit_cnt= global_parameters->select_limit+ - global_parameters->offset_limit; + SELECT_LEX *sl=thd->lex.current_select->master_unit()->first_select(); + offset_limit_cnt= (sl->braces) ? global_parameters->offset_limit : 0; + select_limit_cnt= (sl->braces) ? global_parameters->select_limit+ + global_parameters->offset_limit : HA_POS_ERROR; if (select_limit_cnt < global_parameters->select_limit) select_limit_cnt= HA_POS_ERROR; // no limit if (select_limit_cnt == HA_POS_ERROR) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1fb410b3766..08552fb10a1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1676,12 +1676,17 @@ select_init: '(' SELECT_SYM select_part2 ')' { LEX *lex= Lex; - SELECT_LEX_NODE * sel= lex->current_select; + SELECT_LEX * sel= lex->current_select->select_lex(); if (sel->set_braces(1)) { send_error(lex->thd, ER_SYNTAX_ERROR); YYABORT; } + if (sel->linkage == UNION_TYPE && !sel->master_unit()->first_select()->braces) + { + send_error(lex->thd, ER_SYNTAX_ERROR); + YYABORT; + } /* select in braces, can't contain global parameters */ sel->master_unit()->global_parameters= sel->master_unit(); @@ -1691,11 +1696,17 @@ select_init2: select_part2 { LEX *lex= Lex; + SELECT_LEX * sel= lex->current_select->select_lex(); if (lex->current_select->set_braces(0)) { send_error(lex->thd, ER_SYNTAX_ERROR); YYABORT; } + if (sel->linkage == UNION_TYPE && sel->master_unit()->first_select()->braces) + { + send_error(lex->thd, ER_SYNTAX_ERROR); + YYABORT; + } } union_clause ; @@ -1703,6 +1714,7 @@ select_init2: select_part2: { LEX *lex=Lex; + SELECT_LEX * sel= lex->current_select->select_lex(); if (lex->current_select == &lex->select_lex) lex->lock_option= TL_READ; /* Only for global SELECT */ mysql_init_select(lex); @@ -2517,7 +2529,9 @@ join_table: lex->current_select= unit->outer_select(); if (!($$= lex->current_select-> add_table_to_list(lex->thd, new Table_ident(unit), $5, 0, - lex->lock_option))) + TL_READ,(List<String> *)0, + (List<String> *)0))) + YYABORT; }; @@ -3195,16 +3209,16 @@ table_wild_list: | table_wild_list ',' table_wild_one {}; table_wild_one: - ident opt_wild + ident opt_wild opt_table_alias { - if (!Select->add_table_to_list(YYTHD, new Table_ident($1), NULL, 1, + if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3, 1, Lex->lock_option)) YYABORT; } - | ident '.' ident opt_wild + | ident '.' ident opt_wild opt_table_alias { if (!Select->add_table_to_list(YYTHD, new Table_ident($1, $3, 0), - NULL, 1, Lex->lock_option)) + $5, 1, Lex->lock_option)) YYABORT; } ; |