summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc81
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 */