summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc107
1 files changed, 48 insertions, 59 deletions
diff --git a/sql/table.cc b/sql/table.cc
index a8eeeb53d72..b8ed7a99156 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -46,6 +46,10 @@
#include "sql_show.h"
#include "opt_trace.h"
#include "sql_db.h" // get_default_db_collation
+#include "sql_update.h" // class Sql_cmd_update
+#include "sql_delete.h" // class Sql_cmd_delete
+
+
/* For MySQL 5.7 virtual fields */
#define MYSQL57_GENERATED_FIELD 128
@@ -942,39 +946,6 @@ static uint enum_value_with_check(THD *thd, TABLE_SHARE *share,
}
-/**
- Check if a collation has changed number
-
- @param mysql_version
- @param current collation number
-
- @retval new collation number (same as current collation number of no change)
-*/
-
-static uint upgrade_collation(ulong mysql_version, uint cs_number)
-{
- if (mysql_version >= 50300 && mysql_version <= 50399)
- {
- switch (cs_number) {
- case 149: return MY_PAGE2_COLLATION_ID_UCS2; // ucs2_crotian_ci
- case 213: return MY_PAGE2_COLLATION_ID_UTF8; // utf8_crotian_ci
- }
- }
- if ((mysql_version >= 50500 && mysql_version <= 50599) ||
- (mysql_version >= 100000 && mysql_version <= 100005))
- {
- switch (cs_number) {
- case 149: return MY_PAGE2_COLLATION_ID_UCS2; // ucs2_crotian_ci
- case 213: return MY_PAGE2_COLLATION_ID_UTF8; // utf8_crotian_ci
- case 214: return MY_PAGE2_COLLATION_ID_UTF32; // utf32_croatian_ci
- case 215: return MY_PAGE2_COLLATION_ID_UTF16; // utf16_croatian_ci
- case 245: return MY_PAGE2_COLLATION_ID_UTF8MB4;// utf8mb4_croatian_ci
- }
- }
- return cs_number;
-}
-
-
void Column_definition_attributes::frm_pack_basic(uchar *buff) const
{
int2store(buff + 3, length);
@@ -1034,7 +1005,7 @@ bool Column_definition_attributes::frm_unpack_charset(TABLE_SHARE *share,
const uchar *buff)
{
uint cs_org= buff[14] + (((uint) buff[11]) << 8);
- uint cs_new= upgrade_collation(share->mysql_version, cs_org);
+ uint cs_new= Charset::upgrade_collation_id(share->mysql_version, cs_org);
if (cs_org != cs_new)
share->incompatible_version|= HA_CREATE_USED_CHARSET;
if (cs_new && !(charset= get_charset(cs_new, MYF(0))))
@@ -1894,7 +1865,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (!frm_image[32]) // New frm file in 3.23
{
uint cs_org= (((uint) frm_image[41]) << 8) + (uint) frm_image[38];
- uint cs_new= upgrade_collation(share->mysql_version, cs_org);
+ uint cs_new= Charset::upgrade_collation_id(share->mysql_version, cs_org);
if (cs_org != cs_new)
share->incompatible_version|= HA_CREATE_USED_CHARSET;
@@ -3110,6 +3081,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
goto err;
field= key_part->field= share->field[key_part->fieldnr-1];
+ if (Charset::collation_changed_order(share->mysql_version,
+ field->charset()->number))
+ share->incompatible_version|= HA_CREATE_USED_CHARSET;
key_part->type= field->key_type();
if (field->invisible > INVISIBLE_USER && !field->vers_sys_field())
@@ -3572,7 +3546,6 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
char *sql_copy;
handler *file;
LEX *old_lex;
- Query_arena *arena, backup;
LEX tmp_lex;
KEY *unused1;
uint unused2;
@@ -3599,11 +3572,6 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
old_lex= thd->lex;
thd->lex= &tmp_lex;
- arena= thd->stmt_arena;
- if (arena->is_conventional())
- arena= 0;
- else
- thd->set_n_backup_active_arena(arena, &backup);
/*
THD::reset_db() does not set THD::db_charset,
@@ -3655,8 +3623,6 @@ ret:
lex_end(thd->lex);
thd->reset_db(&db_backup);
thd->lex= old_lex;
- if (arena)
- thd->restore_active_arena(arena, &backup);
reenable_binlog(thd);
thd->variables.character_set_client= old_cs;
if (unlikely(thd->is_error() || error))
@@ -6886,6 +6852,9 @@ bool TABLE_LIST::prepare_security(THD *thd)
#ifndef DBUG_OFF
void TABLE_LIST::set_check_merged()
{
+ if (is_view())
+ return;
+
DBUG_ASSERT(derived);
/*
It is not simple to check all, but at least this should be checked:
@@ -6903,7 +6872,7 @@ void TABLE_LIST::set_check_materialized()
DBUG_ENTER("TABLE_LIST::set_check_materialized");
SELECT_LEX_UNIT *derived= this->derived;
if (view)
- derived= &view->unit;
+ derived= this->derived= &view->unit;
DBUG_ASSERT(derived);
DBUG_ASSERT(!derived->is_excluded());
if (!derived->first_select()->exclude_from_table_unique_test)
@@ -7213,10 +7182,9 @@ void Field_iterator_table_ref::set_field_iterator()
table_ref->alias.str));
}
/* This is a merge view, so use field_translation. */
- else if (table_ref->field_translation &&
- !table_ref->is_materialized_derived())
+ else if (!table_ref->is_materialized_derived() &&
+ table_ref->is_merged_derived() && table_ref->field_translation)
{
- DBUG_ASSERT(table_ref->is_merged_derived());
field_it= &view_field_it;
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_view",
table_ref->alias.str));
@@ -9303,7 +9271,7 @@ bool TABLE::check_period_overlaps(const KEY &key,
return false;
uint kp_len= key.key_part[part_nr].length;
if (f->cmp_prefix(f->ptr_in_record(lhs), f->ptr_in_record(rhs),
- kp_len) != 0)
+ kp_len / f->charset()->mbmaxlen) != 0)
return false;
}
@@ -9722,8 +9690,13 @@ void TABLE_LIST::wrap_into_nested_join(List<TABLE_LIST> &join_list)
static inline bool derived_table_optimization_done(TABLE_LIST *table)
{
- return table->derived &&
- (table->derived->is_excluded() ||
+ SELECT_LEX_UNIT *derived= (table->derived ?
+ table->derived :
+ (table->view ?
+ &table->view->unit:
+ NULL));
+ return derived &&
+ (derived->is_excluded() ||
table->is_materialized_derived());
}
@@ -9785,20 +9758,36 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view)
set_derived();
}
- if (!is_view() &&
- !derived_table_optimization_done(this))
+ if (!derived_table_optimization_done(this))
{
/* A subquery might be forced to be materialized due to a side-effect. */
- bool forced_no_merge_for_update_delete=
- belong_to_view ? belong_to_view->updating :
- !unit->outer_select()->outer_select();
- if (!is_materialized_derived() && first_select->is_mergeable() &&
- (unit->outer_select() && !unit->outer_select()->with_rownum) &&
+ if (!is_materialized_derived() && unit->can_be_merged() &&
+ /*
+ Following is special case of
+ SELECT * FROM (<limited-select>) WHERE ROWNUM() <= nnn
+ */
+ (unit->outer_select() &&
+ !(unit->outer_select()->with_rownum &&
+ unit->outer_select()->table_list.elements == 1 &&
+ (thd->lex->sql_command == SQLCOM_SELECT ||
+ !unit->outer_select()->is_query_topmost(thd)) &&
+ !is_view())) &&
+
(!thd->lex->with_rownum ||
(!first_select->group_list.elements &&
!first_select->order_list.elements)) &&
- optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_MERGE) &&
- !thd->lex->can_not_use_merged(forced_no_merge_for_update_delete) &&
+ (is_view() ||
+ optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_MERGE)) &&
+ !thd->lex->can_not_use_merged() &&
+ !(!is_view() &&
+ (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI ||
+ (thd->lex->sql_command == SQLCOM_UPDATE &&
+ (((Sql_cmd_update *) thd->lex->m_sql_cmd)->is_multitable() ||
+ thd->lex->query_tables->is_multitable())) ||
+ (thd->lex->sql_command == SQLCOM_DELETE &&
+ (((Sql_cmd_delete *) thd->lex->m_sql_cmd)->is_multitable() ||
+ thd->lex->query_tables->is_multitable())))) &&
!is_recursive_with_table())
set_merged_derived();
else