diff options
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 81 |
1 files changed, 53 insertions, 28 deletions
diff --git a/sql/table.cc b/sql/table.cc index 4f647618979..96a10e52dd3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -725,7 +725,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, { share->avg_row_length= uint4korr(head+34); share->row_type= (row_type) head[40]; - share->table_charset= get_charset((uint) head[38],MYF(0)); + share->table_charset= get_charset((((uint) head[41]) << 8) + + (uint) head[38],MYF(0)); share->null_field_first= 1; } if (!share->table_charset) @@ -977,8 +978,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, */ next_chunk+= 4; } - else if (share->mysql_version >= 50110) + else #endif + if (share->mysql_version >= 50110) { /* New auto_partitioned indicator introduced in 5.1.11 */ #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -1183,12 +1185,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } else { - if (!strpos[14]) + uint csid= strpos[14] + (((uint) strpos[11]) << 8); + if (!csid) charset= &my_charset_bin; - else if (!(charset=get_charset((uint) strpos[14], MYF(0)))) + else if (!(charset= get_charset(csid, MYF(0)))) { error= 5; // Unknown or unavailable charset - errarg= (int) strpos[14]; + errarg= (int) csid; goto err; } } @@ -1261,7 +1264,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, "Please do \"ALTER TABLE '%s' FORCE\" to fix it!", share->fieldnames.type_names[i], share->table_name.str, share->table_name.str); - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_CRASHED_ON_USAGE, "Found incompatible DECIMAL field '%s' in %s; " "Please do \"ALTER TABLE '%s' FORCE\" to fix it!", @@ -1463,7 +1466,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, "Please do \"ALTER TABLE '%s' FORCE \" to fix it!", share->table_name.str, share->table_name.str); - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_CRASHED_ON_USAGE, "Found wrong key definition in %s; " "Please do \"ALTER TABLE '%s' FORCE\" to fix " @@ -2456,8 +2459,7 @@ File create_frm(THD *thd, const char *name, const char *db, if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0) { - uint key_length, tmp_key_length; - uint tmp; + uint key_length, tmp_key_length, tmp, csid; bzero((char*) fileinfo,64); /* header */ fileinfo[0]=(uchar) 254; @@ -2497,8 +2499,9 @@ File create_frm(THD *thd, const char *name, const char *db, fileinfo[32]=0; // No filename anymore fileinfo[33]=5; // Mark for 5.0 frm file int4store(fileinfo+34,create_info->avg_row_length); - fileinfo[38]= (create_info->default_table_charset ? - create_info->default_table_charset->number : 0); + csid= (create_info->default_table_charset ? + create_info->default_table_charset->number : 0); + fileinfo[38]= (uchar) csid; /* In future versions, we will store in fileinfo[39] the values of the TRANSACTIONAL and PAGE_CHECKSUM clauses of CREATE TABLE. @@ -2506,7 +2509,7 @@ File create_frm(THD *thd, const char *name, const char *db, fileinfo[39]= 0; fileinfo[40]= (uchar) create_info->row_type; /* Next few bytes where for RAID support */ - fileinfo[41]= 0; + fileinfo[41]= (uchar) (csid >> 8); fileinfo[42]= 0; fileinfo[43]= 0; fileinfo[44]= 0; @@ -3338,7 +3341,12 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type) /** - Hide errors which show view underlying table information + Hide errors which show view underlying table information. + There are currently two mechanisms at work that handle errors for views, + this one and a more general mechanism based on an Internal_error_handler, + see Show_create_error_handler. The latter handles errors encountered during + execution of SHOW CREATE VIEW, while the machanism using this method is + handles SELECT from views. The two methods should not clash. @param[in,out] thd thread handler @@ -3347,23 +3355,25 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type) void TABLE_LIST::hide_view_error(THD *thd) { + if (thd->get_internal_handler()) + return; /* Hide "Unknown column" or "Unknown function" error */ DBUG_ASSERT(thd->is_error()); - if (thd->main_da.sql_errno() == ER_BAD_FIELD_ERROR || - thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST || - thd->main_da.sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION || - thd->main_da.sql_errno() == ER_PROCACCESS_DENIED_ERROR || - thd->main_da.sql_errno() == ER_COLUMNACCESS_DENIED_ERROR || - thd->main_da.sql_errno() == ER_TABLEACCESS_DENIED_ERROR || - thd->main_da.sql_errno() == ER_TABLE_NOT_LOCKED || - thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) + if (thd->stmt_da->sql_errno() == ER_BAD_FIELD_ERROR || + thd->stmt_da->sql_errno() == ER_SP_DOES_NOT_EXIST || + thd->stmt_da->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION || + thd->stmt_da->sql_errno() == ER_PROCACCESS_DENIED_ERROR || + thd->stmt_da->sql_errno() == ER_COLUMNACCESS_DENIED_ERROR || + thd->stmt_da->sql_errno() == ER_TABLEACCESS_DENIED_ERROR || + thd->stmt_da->sql_errno() == ER_TABLE_NOT_LOCKED || + thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) { TABLE_LIST *top= top_table(); thd->clear_error(); my_error(ER_VIEW_INVALID, MYF(0), top->view_db.str, top->view_name.str); } - else if (thd->main_da.sql_errno() == ER_NO_DEFAULT_FOR_FIELD) + else if (thd->stmt_da->sql_errno() == ER_NO_DEFAULT_FOR_FIELD) { TABLE_LIST *top= top_table(); thd->clear_error(); @@ -3441,7 +3451,7 @@ int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure) TABLE_LIST *main_view= top_table(); if (ignore_failure) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED), main_view->view_db.str, main_view->view_name.str); return(VIEW_CHECK_SKIP); @@ -4630,7 +4640,8 @@ Item_subselect *TABLE_LIST::containing_subselect() (TABLE_LIST::index_hints). Using the information in this tagged list this function sets the members st_table::keys_in_use_for_query, st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by, - st_table::force_index and st_table::covering_keys. + st_table::force_index, st_table::force_index_order, + st_table::force_index_group and st_table::covering_keys. Current implementation of the runtime does not allow mixing FORCE INDEX and USE INDEX, so this is checked here. Then the FORCE INDEX list @@ -4758,14 +4769,28 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl) } /* process FORCE INDEX as USE INDEX with a flag */ + if (!index_order[INDEX_HINT_FORCE].is_clear_all()) + { + tbl->force_index_order= TRUE; + index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]); + } + + if (!index_group[INDEX_HINT_FORCE].is_clear_all()) + { + tbl->force_index_group= TRUE; + index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]); + } + + /* + TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) and + create tbl->force_index_join instead. + Then use the correct force_index_XX instead of the global one. + */ if (!index_join[INDEX_HINT_FORCE].is_clear_all() || - !index_order[INDEX_HINT_FORCE].is_clear_all() || - !index_group[INDEX_HINT_FORCE].is_clear_all()) + tbl->force_index_group || tbl->force_index_order) { tbl->force_index= TRUE; index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]); - index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]); - index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]); } /* apply USE INDEX */ |